1 //===- Operation.cpp - Operation support code -----------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "mlir/IR/Operation.h" 10 #include "mlir/IR/BlockAndValueMapping.h" 11 #include "mlir/IR/Diagnostics.h" 12 #include "mlir/IR/Dialect.h" 13 #include "mlir/IR/Function.h" 14 #include "mlir/IR/MLIRContext.h" 15 #include "mlir/IR/OpDefinition.h" 16 #include "mlir/IR/OpImplementation.h" 17 #include "mlir/IR/PatternMatch.h" 18 #include "mlir/IR/StandardTypes.h" 19 #include "mlir/IR/TypeUtilities.h" 20 #include "llvm/Support/CommandLine.h" 21 #include <numeric> 22 23 using namespace mlir; 24 25 static llvm::cl::opt<bool> printOpOnDiagnostic( 26 "mlir-print-op-on-diagnostic", 27 llvm::cl::desc("When a diagnostic is emitted on an operation, also print " 28 "the operation as an attached note")); 29 30 OpAsmParser::~OpAsmParser() {} 31 32 //===----------------------------------------------------------------------===// 33 // OperationName 34 //===----------------------------------------------------------------------===// 35 36 /// Form the OperationName for an op with the specified string. This either is 37 /// a reference to an AbstractOperation if one is known, or a uniqued Identifier 38 /// if not. 39 OperationName::OperationName(StringRef name, MLIRContext *context) { 40 if (auto *op = AbstractOperation::lookup(name, context)) 41 representation = op; 42 else 43 representation = Identifier::get(name, context); 44 } 45 46 /// Return the name of the dialect this operation is registered to. 47 StringRef OperationName::getDialect() const { 48 return getStringRef().split('.').first; 49 } 50 51 /// Return the name of this operation. This always succeeds. 52 StringRef OperationName::getStringRef() const { 53 if (auto *op = representation.dyn_cast<const AbstractOperation *>()) 54 return op->name; 55 return representation.get<Identifier>().strref(); 56 } 57 58 const AbstractOperation *OperationName::getAbstractOperation() const { 59 return representation.dyn_cast<const AbstractOperation *>(); 60 } 61 62 OperationName OperationName::getFromOpaquePointer(void *pointer) { 63 return OperationName(RepresentationUnion::getFromOpaqueValue(pointer)); 64 } 65 66 //===----------------------------------------------------------------------===// 67 // Operation 68 //===----------------------------------------------------------------------===// 69 70 /// Create a new Operation with the specific fields. 71 Operation *Operation::create(Location location, OperationName name, 72 ArrayRef<Type> resultTypes, 73 ArrayRef<Value> operands, 74 ArrayRef<NamedAttribute> attributes, 75 ArrayRef<Block *> successors, unsigned numRegions, 76 bool resizableOperandList) { 77 return create(location, name, resultTypes, operands, 78 NamedAttributeList(attributes), successors, numRegions, 79 resizableOperandList); 80 } 81 82 /// Create a new Operation from operation state. 83 Operation *Operation::create(const OperationState &state) { 84 return Operation::create(state.location, state.name, state.types, 85 state.operands, NamedAttributeList(state.attributes), 86 state.successors, state.regions, 87 state.resizableOperandList); 88 } 89 90 /// Create a new Operation with the specific fields. 91 Operation *Operation::create(Location location, OperationName name, 92 ArrayRef<Type> resultTypes, 93 ArrayRef<Value> operands, 94 NamedAttributeList attributes, 95 ArrayRef<Block *> successors, RegionRange regions, 96 bool resizableOperandList) { 97 unsigned numRegions = regions.size(); 98 Operation *op = create(location, name, resultTypes, operands, attributes, 99 successors, numRegions, resizableOperandList); 100 for (unsigned i = 0; i < numRegions; ++i) 101 if (regions[i]) 102 op->getRegion(i).takeBody(*regions[i]); 103 return op; 104 } 105 106 /// Overload of create that takes an existing NamedAttributeList to avoid 107 /// unnecessarily uniquing a list of attributes. 108 Operation *Operation::create(Location location, OperationName name, 109 ArrayRef<Type> resultTypes, 110 ArrayRef<Value> operands, 111 NamedAttributeList attributes, 112 ArrayRef<Block *> successors, unsigned numRegions, 113 bool resizableOperandList) { 114 unsigned numSuccessors = successors.size(); 115 116 // We only need to allocate additional memory for a subset of results. 117 unsigned numTrailingResults = OpResult::getNumTrailing(resultTypes.size()); 118 119 // Input operands are nullptr-separated for each successor, the null operands 120 // aren't actually stored. 121 unsigned numOperands = operands.size() - numSuccessors; 122 123 // Compute the byte size for the operation and the operand storage. 124 auto byteSize = totalSizeToAlloc<detail::TrailingOpResult, BlockOperand, 125 Region, detail::OperandStorage>( 126 numTrailingResults, numSuccessors, numRegions, 127 /*detail::OperandStorage*/ 1); 128 byteSize += llvm::alignTo(detail::OperandStorage::additionalAllocSize( 129 numOperands, resizableOperandList), 130 alignof(Operation)); 131 void *rawMem = malloc(byteSize); 132 133 // Create the new Operation. 134 auto op = ::new (rawMem) Operation(location, name, resultTypes, numSuccessors, 135 numRegions, attributes); 136 137 assert((numSuccessors == 0 || !op->isKnownNonTerminator()) && 138 "unexpected successors in a non-terminator operation"); 139 140 // Initialize the trailing results. 141 if (LLVM_UNLIKELY(numTrailingResults > 0)) { 142 // We initialize the trailing results with their result number. This makes 143 // 'getResultNumber' checks much more efficient. The main purpose for these 144 // results is to give an anchor to the main operation anyways, so this is 145 // purely an optimization. 146 auto *trailingResultIt = op->getTrailingObjects<detail::TrailingOpResult>(); 147 for (unsigned i = 0; i != numTrailingResults; ++i, ++trailingResultIt) 148 trailingResultIt->trailingResultNumber = i; 149 } 150 151 // Initialize the regions. 152 for (unsigned i = 0; i != numRegions; ++i) 153 new (&op->getRegion(i)) Region(op); 154 155 // Initialize the results and operands. 156 new (&op->getOperandStorage()) 157 detail::OperandStorage(numOperands, resizableOperandList); 158 auto opOperands = op->getOpOperands(); 159 160 // Initialize normal operands. 161 unsigned operandIt = 0, operandE = operands.size(); 162 unsigned nextOperand = 0; 163 for (; operandIt != operandE; ++operandIt) { 164 // Null operands are used as sentinels between successor operand lists. If 165 // we encounter one here, break and handle the successor operands lists 166 // separately below. 167 if (!operands[operandIt]) 168 break; 169 new (&opOperands[nextOperand++]) OpOperand(op, operands[operandIt]); 170 } 171 172 unsigned currentSuccNum = 0; 173 if (operandIt == operandE) { 174 // Verify that the amount of sentinel operands is equivalent to the number 175 // of successors. 176 assert(currentSuccNum == numSuccessors); 177 return op; 178 } 179 180 assert(!op->isKnownNonTerminator() && 181 "Unexpected nullptr in operand list when creating non-terminator."); 182 auto instBlockOperands = op->getBlockOperands(); 183 unsigned *succOperandCount = nullptr; 184 185 for (; operandIt != operandE; ++operandIt) { 186 // If we encounter a sentinel branch to the next operand update the count 187 // variable. 188 if (!operands[operandIt]) { 189 assert(currentSuccNum < numSuccessors); 190 191 new (&instBlockOperands[currentSuccNum]) 192 BlockOperand(op, successors[currentSuccNum]); 193 succOperandCount = 194 &instBlockOperands[currentSuccNum].numSuccessorOperands; 195 ++currentSuccNum; 196 continue; 197 } 198 new (&opOperands[nextOperand++]) OpOperand(op, operands[operandIt]); 199 ++(*succOperandCount); 200 } 201 202 // Verify that the amount of sentinel operands is equivalent to the number of 203 // successors. 204 assert(currentSuccNum == numSuccessors); 205 206 return op; 207 } 208 209 Operation::Operation(Location location, OperationName name, 210 ArrayRef<Type> resultTypes, unsigned numSuccessors, 211 unsigned numRegions, const NamedAttributeList &attributes) 212 : location(location), numSuccs(numSuccessors), numRegions(numRegions), 213 hasSingleResult(false), name(name), attrs(attributes) { 214 if (!resultTypes.empty()) { 215 // If there is a single result it is stored in-place, otherwise use a tuple. 216 hasSingleResult = resultTypes.size() == 1; 217 if (hasSingleResult) 218 resultType = resultTypes.front(); 219 else 220 resultType = TupleType::get(resultTypes, location->getContext()); 221 } 222 } 223 224 // Operations are deleted through the destroy() member because they are 225 // allocated via malloc. 226 Operation::~Operation() { 227 assert(block == nullptr && "operation destroyed but still in a block"); 228 229 // Explicitly run the destructors for the operands and results. 230 getOperandStorage().~OperandStorage(); 231 232 // Explicitly run the destructors for the successors. 233 for (auto &successor : getBlockOperands()) 234 successor.~BlockOperand(); 235 236 // Explicitly destroy the regions. 237 for (auto ®ion : getRegions()) 238 region.~Region(); 239 } 240 241 /// Destroy this operation or one of its subclasses. 242 void Operation::destroy() { 243 this->~Operation(); 244 free(this); 245 } 246 247 /// Return the context this operation is associated with. 248 MLIRContext *Operation::getContext() { return location->getContext(); } 249 250 /// Return the dialect this operation is associated with, or nullptr if the 251 /// associated dialect is not registered. 252 Dialect *Operation::getDialect() { 253 if (auto *abstractOp = getAbstractOperation()) 254 return &abstractOp->dialect; 255 256 // If this operation hasn't been registered or doesn't have abstract 257 // operation, try looking up the dialect name in the context. 258 return getContext()->getRegisteredDialect(getName().getDialect()); 259 } 260 261 Region *Operation::getParentRegion() { 262 return block ? block->getParent() : nullptr; 263 } 264 265 Operation *Operation::getParentOp() { 266 return block ? block->getParentOp() : nullptr; 267 } 268 269 /// Return true if this operation is a proper ancestor of the `other` 270 /// operation. 271 bool Operation::isProperAncestor(Operation *other) { 272 while ((other = other->getParentOp())) 273 if (this == other) 274 return true; 275 return false; 276 } 277 278 /// Replace any uses of 'from' with 'to' within this operation. 279 void Operation::replaceUsesOfWith(Value from, Value to) { 280 if (from == to) 281 return; 282 for (auto &operand : getOpOperands()) 283 if (operand.get() == from) 284 operand.set(to); 285 } 286 287 /// Replace the current operands of this operation with the ones provided in 288 /// 'operands'. If the operands list is not resizable, the size of 'operands' 289 /// must be less than or equal to the current number of operands. 290 void Operation::setOperands(ValueRange operands) { 291 getOperandStorage().setOperands(this, operands); 292 } 293 294 //===----------------------------------------------------------------------===// 295 // Diagnostics 296 //===----------------------------------------------------------------------===// 297 298 /// Emit an error about fatal conditions with this operation, reporting up to 299 /// any diagnostic handlers that may be listening. 300 InFlightDiagnostic Operation::emitError(const Twine &message) { 301 InFlightDiagnostic diag = mlir::emitError(getLoc(), message); 302 if (printOpOnDiagnostic) { 303 // Print out the operation explicitly here so that we can print the generic 304 // form. 305 // TODO(riverriddle) It would be nice if we could instead provide the 306 // specific printing flags when adding the operation as an argument to the 307 // diagnostic. 308 std::string printedOp; 309 { 310 llvm::raw_string_ostream os(printedOp); 311 print(os, OpPrintingFlags().printGenericOpForm().useLocalScope()); 312 } 313 diag.attachNote(getLoc()) << "see current operation: " << printedOp; 314 } 315 return diag; 316 } 317 318 /// Emit a warning about this operation, reporting up to any diagnostic 319 /// handlers that may be listening. 320 InFlightDiagnostic Operation::emitWarning(const Twine &message) { 321 InFlightDiagnostic diag = mlir::emitWarning(getLoc(), message); 322 if (printOpOnDiagnostic) 323 diag.attachNote(getLoc()) << "see current operation: " << *this; 324 return diag; 325 } 326 327 /// Emit a remark about this operation, reporting up to any diagnostic 328 /// handlers that may be listening. 329 InFlightDiagnostic Operation::emitRemark(const Twine &message) { 330 InFlightDiagnostic diag = mlir::emitRemark(getLoc(), message); 331 if (printOpOnDiagnostic) 332 diag.attachNote(getLoc()) << "see current operation: " << *this; 333 return diag; 334 } 335 336 //===----------------------------------------------------------------------===// 337 // Operation Ordering 338 //===----------------------------------------------------------------------===// 339 340 constexpr unsigned Operation::kInvalidOrderIdx; 341 constexpr unsigned Operation::kOrderStride; 342 343 /// Given an operation 'other' that is within the same parent block, return 344 /// whether the current operation is before 'other' in the operation list 345 /// of the parent block. 346 /// Note: This function has an average complexity of O(1), but worst case may 347 /// take O(N) where N is the number of operations within the parent block. 348 bool Operation::isBeforeInBlock(Operation *other) { 349 assert(block && "Operations without parent blocks have no order."); 350 assert(other && other->block == block && 351 "Expected other operation to have the same parent block."); 352 // If the order of the block is already invalid, directly recompute the 353 // parent. 354 if (!block->isOpOrderValid()) { 355 block->recomputeOpOrder(); 356 } else { 357 // Update the order either operation if necessary. 358 updateOrderIfNecessary(); 359 other->updateOrderIfNecessary(); 360 } 361 362 return orderIndex < other->orderIndex; 363 } 364 365 /// Update the order index of this operation of this operation if necessary, 366 /// potentially recomputing the order of the parent block. 367 void Operation::updateOrderIfNecessary() { 368 assert(block && "expected valid parent"); 369 370 // If the order is valid for this operation there is nothing to do. 371 if (hasValidOrder()) 372 return; 373 Operation *blockFront = &block->front(); 374 Operation *blockBack = &block->back(); 375 376 // This method is expected to only be invoked on blocks with more than one 377 // operation. 378 assert(blockFront != blockBack && "expected more than one operation"); 379 380 // If the operation is at the end of the block. 381 if (this == blockBack) { 382 Operation *prevNode = getPrevNode(); 383 if (!prevNode->hasValidOrder()) 384 return block->recomputeOpOrder(); 385 386 // Add the stride to the previous operation. 387 orderIndex = prevNode->orderIndex + kOrderStride; 388 return; 389 } 390 391 // If this is the first operation try to use the next operation to compute the 392 // ordering. 393 if (this == blockFront) { 394 Operation *nextNode = getNextNode(); 395 if (!nextNode->hasValidOrder()) 396 return block->recomputeOpOrder(); 397 // There is no order to give this operation. 398 if (nextNode->orderIndex == 0) 399 return block->recomputeOpOrder(); 400 401 // If we can't use the stride, just take the middle value left. This is safe 402 // because we know there is at least one valid index to assign to. 403 if (nextNode->orderIndex <= kOrderStride) 404 orderIndex = (nextNode->orderIndex / 2); 405 else 406 orderIndex = kOrderStride; 407 return; 408 } 409 410 // Otherwise, this operation is between two others. Place this operation in 411 // the middle of the previous and next if possible. 412 Operation *prevNode = getPrevNode(), *nextNode = getNextNode(); 413 if (!prevNode->hasValidOrder() || !nextNode->hasValidOrder()) 414 return block->recomputeOpOrder(); 415 unsigned prevOrder = prevNode->orderIndex, nextOrder = nextNode->orderIndex; 416 417 // Check to see if there is a valid order between the two. 418 if (prevOrder + 1 == nextOrder) 419 return block->recomputeOpOrder(); 420 orderIndex = prevOrder + 1 + ((nextOrder - prevOrder) / 2); 421 } 422 423 //===----------------------------------------------------------------------===// 424 // ilist_traits for Operation 425 //===----------------------------------------------------------------------===// 426 427 auto llvm::ilist_detail::SpecificNodeAccess< 428 typename llvm::ilist_detail::compute_node_options< 429 ::mlir::Operation>::type>::getNodePtr(pointer N) -> node_type * { 430 return NodeAccess::getNodePtr<OptionsT>(N); 431 } 432 433 auto llvm::ilist_detail::SpecificNodeAccess< 434 typename llvm::ilist_detail::compute_node_options< 435 ::mlir::Operation>::type>::getNodePtr(const_pointer N) 436 -> const node_type * { 437 return NodeAccess::getNodePtr<OptionsT>(N); 438 } 439 440 auto llvm::ilist_detail::SpecificNodeAccess< 441 typename llvm::ilist_detail::compute_node_options< 442 ::mlir::Operation>::type>::getValuePtr(node_type *N) -> pointer { 443 return NodeAccess::getValuePtr<OptionsT>(N); 444 } 445 446 auto llvm::ilist_detail::SpecificNodeAccess< 447 typename llvm::ilist_detail::compute_node_options< 448 ::mlir::Operation>::type>::getValuePtr(const node_type *N) 449 -> const_pointer { 450 return NodeAccess::getValuePtr<OptionsT>(N); 451 } 452 453 void llvm::ilist_traits<::mlir::Operation>::deleteNode(Operation *op) { 454 op->destroy(); 455 } 456 457 Block *llvm::ilist_traits<::mlir::Operation>::getContainingBlock() { 458 size_t Offset(size_t(&((Block *)nullptr->*Block::getSublistAccess(nullptr)))); 459 iplist<Operation> *Anchor(static_cast<iplist<Operation> *>(this)); 460 return reinterpret_cast<Block *>(reinterpret_cast<char *>(Anchor) - Offset); 461 } 462 463 /// This is a trait method invoked when a operation is added to a block. We 464 /// keep the block pointer up to date. 465 void llvm::ilist_traits<::mlir::Operation>::addNodeToList(Operation *op) { 466 assert(!op->getBlock() && "already in a operation block!"); 467 op->block = getContainingBlock(); 468 469 // Invalidate the order on the operation. 470 op->orderIndex = Operation::kInvalidOrderIdx; 471 } 472 473 /// This is a trait method invoked when a operation is removed from a block. 474 /// We keep the block pointer up to date. 475 void llvm::ilist_traits<::mlir::Operation>::removeNodeFromList(Operation *op) { 476 assert(op->block && "not already in a operation block!"); 477 op->block = nullptr; 478 } 479 480 /// This is a trait method invoked when a operation is moved from one block 481 /// to another. We keep the block pointer up to date. 482 void llvm::ilist_traits<::mlir::Operation>::transferNodesFromList( 483 ilist_traits<Operation> &otherList, op_iterator first, op_iterator last) { 484 Block *curParent = getContainingBlock(); 485 486 // Invalidate the ordering of the parent block. 487 curParent->invalidateOpOrder(); 488 489 // If we are transferring operations within the same block, the block 490 // pointer doesn't need to be updated. 491 if (curParent == otherList.getContainingBlock()) 492 return; 493 494 // Update the 'block' member of each operation. 495 for (; first != last; ++first) 496 first->block = curParent; 497 } 498 499 /// Remove this operation (and its descendants) from its Block and delete 500 /// all of them. 501 void Operation::erase() { 502 if (auto *parent = getBlock()) 503 parent->getOperations().erase(this); 504 else 505 destroy(); 506 } 507 508 /// Unlink this operation from its current block and insert it right before 509 /// `existingOp` which may be in the same or another block in the same 510 /// function. 511 void Operation::moveBefore(Operation *existingOp) { 512 moveBefore(existingOp->getBlock(), existingOp->getIterator()); 513 } 514 515 /// Unlink this operation from its current basic block and insert it right 516 /// before `iterator` in the specified basic block. 517 void Operation::moveBefore(Block *block, 518 llvm::iplist<Operation>::iterator iterator) { 519 block->getOperations().splice(iterator, getBlock()->getOperations(), 520 getIterator()); 521 } 522 523 /// This drops all operand uses from this operation, which is an essential 524 /// step in breaking cyclic dependences between references when they are to 525 /// be deleted. 526 void Operation::dropAllReferences() { 527 for (auto &op : getOpOperands()) 528 op.drop(); 529 530 for (auto ®ion : getRegions()) 531 region.dropAllReferences(); 532 533 for (auto &dest : getBlockOperands()) 534 dest.drop(); 535 } 536 537 /// This drops all uses of any values defined by this operation or its nested 538 /// regions, wherever they are located. 539 void Operation::dropAllDefinedValueUses() { 540 dropAllUses(); 541 542 for (auto ®ion : getRegions()) 543 for (auto &block : region) 544 block.dropAllDefinedValueUses(); 545 } 546 547 /// Return the number of results held by this operation. 548 unsigned Operation::getNumResults() { 549 if (!resultType) 550 return 0; 551 return hasSingleResult ? 1 : resultType.cast<TupleType>().size(); 552 } 553 554 auto Operation::getResultTypes() -> result_type_range { 555 if (!resultType) 556 return llvm::None; 557 if (hasSingleResult) 558 return resultType; 559 return resultType.cast<TupleType>().getTypes(); 560 } 561 562 void Operation::setSuccessor(Block *block, unsigned index) { 563 assert(index < getNumSuccessors()); 564 getBlockOperands()[index].set(block); 565 } 566 567 auto Operation::getNonSuccessorOperands() -> operand_range { 568 return getOperands().take_front(hasSuccessors() ? getSuccessorOperandIndex(0) 569 : getNumOperands()); 570 } 571 572 /// Get the index of the first operand of the successor at the provided 573 /// index. 574 unsigned Operation::getSuccessorOperandIndex(unsigned index) { 575 assert(!isKnownNonTerminator() && "only terminators may have successors"); 576 assert(index < getNumSuccessors()); 577 578 // Count the number of operands for each of the successors after, and 579 // including, the one at 'index'. This is based upon the assumption that all 580 // non successor operands are placed at the beginning of the operand list. 581 auto blockOperands = getBlockOperands().drop_front(index); 582 unsigned postSuccessorOpCount = 583 std::accumulate(blockOperands.begin(), blockOperands.end(), 0u, 584 [](unsigned cur, const BlockOperand &operand) { 585 return cur + operand.numSuccessorOperands; 586 }); 587 return getNumOperands() - postSuccessorOpCount; 588 } 589 590 Optional<std::pair<unsigned, unsigned>> 591 Operation::decomposeSuccessorOperandIndex(unsigned operandIndex) { 592 assert(!isKnownNonTerminator() && "only terminators may have successors"); 593 assert(operandIndex < getNumOperands()); 594 unsigned currentOperandIndex = getNumOperands(); 595 auto blockOperands = getBlockOperands(); 596 for (unsigned i = 0, e = getNumSuccessors(); i < e; i++) { 597 unsigned successorIndex = e - i - 1; 598 currentOperandIndex -= blockOperands[successorIndex].numSuccessorOperands; 599 if (currentOperandIndex <= operandIndex) 600 return std::make_pair(successorIndex, operandIndex - currentOperandIndex); 601 } 602 return None; 603 } 604 605 auto Operation::getSuccessorOperands(unsigned index) -> operand_range { 606 unsigned succOperandIndex = getSuccessorOperandIndex(index); 607 return getOperands().slice(succOperandIndex, getNumSuccessorOperands(index)); 608 } 609 610 /// Attempt to fold this operation using the Op's registered foldHook. 611 LogicalResult Operation::fold(ArrayRef<Attribute> operands, 612 SmallVectorImpl<OpFoldResult> &results) { 613 // If we have a registered operation definition matching this one, use it to 614 // try to constant fold the operation. 615 auto *abstractOp = getAbstractOperation(); 616 if (abstractOp && succeeded(abstractOp->foldHook(this, operands, results))) 617 return success(); 618 619 // Otherwise, fall back on the dialect hook to handle it. 620 Dialect *dialect = getDialect(); 621 if (!dialect) 622 return failure(); 623 624 SmallVector<Attribute, 8> constants; 625 if (failed(dialect->constantFoldHook(this, operands, constants))) 626 return failure(); 627 results.assign(constants.begin(), constants.end()); 628 return success(); 629 } 630 631 /// Emit an error with the op name prefixed, like "'dim' op " which is 632 /// convenient for verifiers. 633 InFlightDiagnostic Operation::emitOpError(const Twine &message) { 634 return emitError() << "'" << getName() << "' op " << message; 635 } 636 637 //===----------------------------------------------------------------------===// 638 // Operation Cloning 639 //===----------------------------------------------------------------------===// 640 641 /// Create a deep copy of this operation but keep the operation regions empty. 642 /// Operands are remapped using `mapper` (if present), and `mapper` is updated 643 /// to contain the results. 644 Operation *Operation::cloneWithoutRegions(BlockAndValueMapping &mapper) { 645 SmallVector<Value, 8> operands; 646 SmallVector<Block *, 2> successors; 647 648 operands.reserve(getNumOperands() + getNumSuccessors()); 649 650 if (getNumSuccessors() == 0) { 651 // Non-branching operations can just add all the operands. 652 for (auto opValue : getOperands()) 653 operands.push_back(mapper.lookupOrDefault(opValue)); 654 } else { 655 // We add the operands separated by nullptr's for each successor. 656 unsigned firstSuccOperand = 657 getNumSuccessors() ? getSuccessorOperandIndex(0) : getNumOperands(); 658 auto opOperands = getOpOperands(); 659 660 unsigned i = 0; 661 for (; i != firstSuccOperand; ++i) 662 operands.push_back(mapper.lookupOrDefault(opOperands[i].get())); 663 664 successors.reserve(getNumSuccessors()); 665 for (unsigned succ = 0, e = getNumSuccessors(); succ != e; ++succ) { 666 successors.push_back(mapper.lookupOrDefault(getSuccessor(succ))); 667 668 // Add sentinel to delineate successor operands. 669 operands.push_back(nullptr); 670 671 // Remap the successors operands. 672 for (auto operand : getSuccessorOperands(succ)) 673 operands.push_back(mapper.lookupOrDefault(operand)); 674 } 675 } 676 677 unsigned numRegions = getNumRegions(); 678 auto *newOp = 679 Operation::create(getLoc(), getName(), getResultTypes(), operands, attrs, 680 successors, numRegions, hasResizableOperandsList()); 681 682 // Remember the mapping of any results. 683 for (unsigned i = 0, e = getNumResults(); i != e; ++i) 684 mapper.map(getResult(i), newOp->getResult(i)); 685 686 return newOp; 687 } 688 689 Operation *Operation::cloneWithoutRegions() { 690 BlockAndValueMapping mapper; 691 return cloneWithoutRegions(mapper); 692 } 693 694 /// Create a deep copy of this operation, remapping any operands that use 695 /// values outside of the operation using the map that is provided (leaving 696 /// them alone if no entry is present). Replaces references to cloned 697 /// sub-operations to the corresponding operation that is copied, and adds 698 /// those mappings to the map. 699 Operation *Operation::clone(BlockAndValueMapping &mapper) { 700 auto *newOp = cloneWithoutRegions(mapper); 701 702 // Clone the regions. 703 for (unsigned i = 0; i != numRegions; ++i) 704 getRegion(i).cloneInto(&newOp->getRegion(i), mapper); 705 706 return newOp; 707 } 708 709 Operation *Operation::clone() { 710 BlockAndValueMapping mapper; 711 return clone(mapper); 712 } 713 714 //===----------------------------------------------------------------------===// 715 // OpState trait class. 716 //===----------------------------------------------------------------------===// 717 718 // The fallback for the parser is to reject the custom assembly form. 719 ParseResult OpState::parse(OpAsmParser &parser, OperationState &result) { 720 return parser.emitError(parser.getNameLoc(), "has no custom assembly form"); 721 } 722 723 // The fallback for the printer is to print in the generic assembly form. 724 void OpState::print(OpAsmPrinter &p) { p.printGenericOp(getOperation()); } 725 726 /// Emit an error about fatal conditions with this operation, reporting up to 727 /// any diagnostic handlers that may be listening. 728 InFlightDiagnostic OpState::emitError(const Twine &message) { 729 return getOperation()->emitError(message); 730 } 731 732 /// Emit an error with the op name prefixed, like "'dim' op " which is 733 /// convenient for verifiers. 734 InFlightDiagnostic OpState::emitOpError(const Twine &message) { 735 return getOperation()->emitOpError(message); 736 } 737 738 /// Emit a warning about this operation, reporting up to any diagnostic 739 /// handlers that may be listening. 740 InFlightDiagnostic OpState::emitWarning(const Twine &message) { 741 return getOperation()->emitWarning(message); 742 } 743 744 /// Emit a remark about this operation, reporting up to any diagnostic 745 /// handlers that may be listening. 746 InFlightDiagnostic OpState::emitRemark(const Twine &message) { 747 return getOperation()->emitRemark(message); 748 } 749 750 //===----------------------------------------------------------------------===// 751 // Op Trait implementations 752 //===----------------------------------------------------------------------===// 753 754 LogicalResult OpTrait::impl::verifyZeroOperands(Operation *op) { 755 if (op->getNumOperands() != 0) 756 return op->emitOpError() << "requires zero operands"; 757 return success(); 758 } 759 760 LogicalResult OpTrait::impl::verifyOneOperand(Operation *op) { 761 if (op->getNumOperands() != 1) 762 return op->emitOpError() << "requires a single operand"; 763 return success(); 764 } 765 766 LogicalResult OpTrait::impl::verifyNOperands(Operation *op, 767 unsigned numOperands) { 768 if (op->getNumOperands() != numOperands) { 769 return op->emitOpError() << "expected " << numOperands 770 << " operands, but found " << op->getNumOperands(); 771 } 772 return success(); 773 } 774 775 LogicalResult OpTrait::impl::verifyAtLeastNOperands(Operation *op, 776 unsigned numOperands) { 777 if (op->getNumOperands() < numOperands) 778 return op->emitOpError() 779 << "expected " << numOperands << " or more operands"; 780 return success(); 781 } 782 783 /// If this is a vector type, or a tensor type, return the scalar element type 784 /// that it is built around, otherwise return the type unmodified. 785 static Type getTensorOrVectorElementType(Type type) { 786 if (auto vec = type.dyn_cast<VectorType>()) 787 return vec.getElementType(); 788 789 // Look through tensor<vector<...>> to find the underlying element type. 790 if (auto tensor = type.dyn_cast<TensorType>()) 791 return getTensorOrVectorElementType(tensor.getElementType()); 792 return type; 793 } 794 795 LogicalResult OpTrait::impl::verifyOperandsAreIntegerLike(Operation *op) { 796 for (auto opType : op->getOperandTypes()) { 797 auto type = getTensorOrVectorElementType(opType); 798 if (!type.isIntOrIndex()) 799 return op->emitOpError() << "requires an integer or index type"; 800 } 801 return success(); 802 } 803 804 LogicalResult OpTrait::impl::verifyOperandsAreFloatLike(Operation *op) { 805 for (auto opType : op->getOperandTypes()) { 806 auto type = getTensorOrVectorElementType(opType); 807 if (!type.isa<FloatType>()) 808 return op->emitOpError("requires a float type"); 809 } 810 return success(); 811 } 812 813 LogicalResult OpTrait::impl::verifySameTypeOperands(Operation *op) { 814 // Zero or one operand always have the "same" type. 815 unsigned nOperands = op->getNumOperands(); 816 if (nOperands < 2) 817 return success(); 818 819 auto type = op->getOperand(0).getType(); 820 for (auto opType : llvm::drop_begin(op->getOperandTypes(), 1)) 821 if (opType != type) 822 return op->emitOpError() << "requires all operands to have the same type"; 823 return success(); 824 } 825 826 LogicalResult OpTrait::impl::verifyZeroResult(Operation *op) { 827 if (op->getNumResults() != 0) 828 return op->emitOpError() << "requires zero results"; 829 return success(); 830 } 831 832 LogicalResult OpTrait::impl::verifyOneResult(Operation *op) { 833 if (op->getNumResults() != 1) 834 return op->emitOpError() << "requires one result"; 835 return success(); 836 } 837 838 LogicalResult OpTrait::impl::verifyNResults(Operation *op, 839 unsigned numOperands) { 840 if (op->getNumResults() != numOperands) 841 return op->emitOpError() << "expected " << numOperands << " results"; 842 return success(); 843 } 844 845 LogicalResult OpTrait::impl::verifyAtLeastNResults(Operation *op, 846 unsigned numOperands) { 847 if (op->getNumResults() < numOperands) 848 return op->emitOpError() 849 << "expected " << numOperands << " or more results"; 850 return success(); 851 } 852 853 LogicalResult OpTrait::impl::verifySameOperandsShape(Operation *op) { 854 if (failed(verifyAtLeastNOperands(op, 1))) 855 return failure(); 856 857 auto type = op->getOperand(0).getType(); 858 for (auto opType : llvm::drop_begin(op->getOperandTypes(), 1)) { 859 if (failed(verifyCompatibleShape(opType, type))) 860 return op->emitOpError() << "requires the same shape for all operands"; 861 } 862 return success(); 863 } 864 865 LogicalResult OpTrait::impl::verifySameOperandsAndResultShape(Operation *op) { 866 if (failed(verifyAtLeastNOperands(op, 1)) || 867 failed(verifyAtLeastNResults(op, 1))) 868 return failure(); 869 870 auto type = op->getOperand(0).getType(); 871 for (auto resultType : op->getResultTypes()) { 872 if (failed(verifyCompatibleShape(resultType, type))) 873 return op->emitOpError() 874 << "requires the same shape for all operands and results"; 875 } 876 for (auto opType : llvm::drop_begin(op->getOperandTypes(), 1)) { 877 if (failed(verifyCompatibleShape(opType, type))) 878 return op->emitOpError() 879 << "requires the same shape for all operands and results"; 880 } 881 return success(); 882 } 883 884 LogicalResult OpTrait::impl::verifySameOperandsElementType(Operation *op) { 885 if (failed(verifyAtLeastNOperands(op, 1))) 886 return failure(); 887 auto elementType = getElementTypeOrSelf(op->getOperand(0)); 888 889 for (auto operand : llvm::drop_begin(op->getOperands(), 1)) { 890 if (getElementTypeOrSelf(operand) != elementType) 891 return op->emitOpError("requires the same element type for all operands"); 892 } 893 894 return success(); 895 } 896 897 LogicalResult 898 OpTrait::impl::verifySameOperandsAndResultElementType(Operation *op) { 899 if (failed(verifyAtLeastNOperands(op, 1)) || 900 failed(verifyAtLeastNResults(op, 1))) 901 return failure(); 902 903 auto elementType = getElementTypeOrSelf(op->getResult(0)); 904 905 // Verify result element type matches first result's element type. 906 for (auto result : llvm::drop_begin(op->getResults(), 1)) { 907 if (getElementTypeOrSelf(result) != elementType) 908 return op->emitOpError( 909 "requires the same element type for all operands and results"); 910 } 911 912 // Verify operand's element type matches first result's element type. 913 for (auto operand : op->getOperands()) { 914 if (getElementTypeOrSelf(operand) != elementType) 915 return op->emitOpError( 916 "requires the same element type for all operands and results"); 917 } 918 919 return success(); 920 } 921 922 LogicalResult OpTrait::impl::verifySameOperandsAndResultType(Operation *op) { 923 if (failed(verifyAtLeastNOperands(op, 1)) || 924 failed(verifyAtLeastNResults(op, 1))) 925 return failure(); 926 927 auto type = op->getResult(0).getType(); 928 auto elementType = getElementTypeOrSelf(type); 929 for (auto resultType : op->getResultTypes().drop_front(1)) { 930 if (getElementTypeOrSelf(resultType) != elementType || 931 failed(verifyCompatibleShape(resultType, type))) 932 return op->emitOpError() 933 << "requires the same type for all operands and results"; 934 } 935 for (auto opType : op->getOperandTypes()) { 936 if (getElementTypeOrSelf(opType) != elementType || 937 failed(verifyCompatibleShape(opType, type))) 938 return op->emitOpError() 939 << "requires the same type for all operands and results"; 940 } 941 return success(); 942 } 943 944 static LogicalResult verifySuccessor(Operation *op, unsigned succNo) { 945 Operation::operand_range operands = op->getSuccessorOperands(succNo); 946 unsigned operandCount = op->getNumSuccessorOperands(succNo); 947 Block *destBB = op->getSuccessor(succNo); 948 if (operandCount != destBB->getNumArguments()) 949 return op->emitError() << "branch has " << operandCount 950 << " operands for successor #" << succNo 951 << ", but target block has " 952 << destBB->getNumArguments(); 953 954 auto operandIt = operands.begin(); 955 for (unsigned i = 0, e = operandCount; i != e; ++i, ++operandIt) { 956 if ((*operandIt).getType() != destBB->getArgument(i).getType()) 957 return op->emitError() << "type mismatch for bb argument #" << i 958 << " of successor #" << succNo; 959 } 960 961 return success(); 962 } 963 964 static LogicalResult verifyTerminatorSuccessors(Operation *op) { 965 auto *parent = op->getParentRegion(); 966 967 // Verify that the operands lines up with the BB arguments in the successor. 968 for (unsigned i = 0, e = op->getNumSuccessors(); i != e; ++i) { 969 auto *succ = op->getSuccessor(i); 970 if (succ->getParent() != parent) 971 return op->emitError("reference to block defined in another region"); 972 if (failed(verifySuccessor(op, i))) 973 return failure(); 974 } 975 return success(); 976 } 977 978 LogicalResult OpTrait::impl::verifyIsTerminator(Operation *op) { 979 Block *block = op->getBlock(); 980 // Verify that the operation is at the end of the respective parent block. 981 if (!block || &block->back() != op) 982 return op->emitOpError("must be the last operation in the parent block"); 983 984 // Verify the state of the successor blocks. 985 if (op->getNumSuccessors() != 0 && failed(verifyTerminatorSuccessors(op))) 986 return failure(); 987 return success(); 988 } 989 990 LogicalResult OpTrait::impl::verifyResultsAreBoolLike(Operation *op) { 991 for (auto resultType : op->getResultTypes()) { 992 auto elementType = getTensorOrVectorElementType(resultType); 993 bool isBoolType = elementType.isInteger(1); 994 if (!isBoolType) 995 return op->emitOpError() << "requires a bool result type"; 996 } 997 998 return success(); 999 } 1000 1001 LogicalResult OpTrait::impl::verifyResultsAreFloatLike(Operation *op) { 1002 for (auto resultType : op->getResultTypes()) 1003 if (!getTensorOrVectorElementType(resultType).isa<FloatType>()) 1004 return op->emitOpError() << "requires a floating point type"; 1005 1006 return success(); 1007 } 1008 1009 LogicalResult OpTrait::impl::verifyResultsAreIntegerLike(Operation *op) { 1010 for (auto resultType : op->getResultTypes()) 1011 if (!getTensorOrVectorElementType(resultType).isIntOrIndex()) 1012 return op->emitOpError() << "requires an integer or index type"; 1013 return success(); 1014 } 1015 1016 static LogicalResult verifyValueSizeAttr(Operation *op, StringRef attrName, 1017 bool isOperand) { 1018 auto sizeAttr = op->getAttrOfType<DenseIntElementsAttr>(attrName); 1019 if (!sizeAttr) 1020 return op->emitOpError("requires 1D vector attribute '") << attrName << "'"; 1021 1022 auto sizeAttrType = sizeAttr.getType().dyn_cast<VectorType>(); 1023 if (!sizeAttrType || sizeAttrType.getRank() != 1) 1024 return op->emitOpError("requires 1D vector attribute '") << attrName << "'"; 1025 1026 if (llvm::any_of(sizeAttr.getIntValues(), [](const APInt &element) { 1027 return !element.isNonNegative(); 1028 })) 1029 return op->emitOpError("'") 1030 << attrName << "' attribute cannot have negative elements"; 1031 1032 size_t totalCount = std::accumulate( 1033 sizeAttr.begin(), sizeAttr.end(), 0, 1034 [](unsigned all, APInt one) { return all + one.getZExtValue(); }); 1035 1036 if (isOperand && totalCount != op->getNumOperands()) 1037 return op->emitOpError("operand count (") 1038 << op->getNumOperands() << ") does not match with the total size (" 1039 << totalCount << ") specified in attribute '" << attrName << "'"; 1040 else if (!isOperand && totalCount != op->getNumResults()) 1041 return op->emitOpError("result count (") 1042 << op->getNumResults() << ") does not match with the total size (" 1043 << totalCount << ") specified in attribute '" << attrName << "'"; 1044 return success(); 1045 } 1046 1047 LogicalResult OpTrait::impl::verifyOperandSizeAttr(Operation *op, 1048 StringRef attrName) { 1049 return verifyValueSizeAttr(op, attrName, /*isOperand=*/true); 1050 } 1051 1052 LogicalResult OpTrait::impl::verifyResultSizeAttr(Operation *op, 1053 StringRef attrName) { 1054 return verifyValueSizeAttr(op, attrName, /*isOperand=*/false); 1055 } 1056 1057 //===----------------------------------------------------------------------===// 1058 // BinaryOp implementation 1059 //===----------------------------------------------------------------------===// 1060 1061 // These functions are out-of-line implementations of the methods in BinaryOp, 1062 // which avoids them being template instantiated/duplicated. 1063 1064 void impl::buildBinaryOp(Builder *builder, OperationState &result, Value lhs, 1065 Value rhs) { 1066 assert(lhs.getType() == rhs.getType()); 1067 result.addOperands({lhs, rhs}); 1068 result.types.push_back(lhs.getType()); 1069 } 1070 1071 ParseResult impl::parseOneResultSameOperandTypeOp(OpAsmParser &parser, 1072 OperationState &result) { 1073 SmallVector<OpAsmParser::OperandType, 2> ops; 1074 Type type; 1075 return failure(parser.parseOperandList(ops) || 1076 parser.parseOptionalAttrDict(result.attributes) || 1077 parser.parseColonType(type) || 1078 parser.resolveOperands(ops, type, result.operands) || 1079 parser.addTypeToList(type, result.types)); 1080 } 1081 1082 void impl::printOneResultOp(Operation *op, OpAsmPrinter &p) { 1083 assert(op->getNumResults() == 1 && "op should have one result"); 1084 1085 // If not all the operand and result types are the same, just use the 1086 // generic assembly form to avoid omitting information in printing. 1087 auto resultType = op->getResult(0).getType(); 1088 if (llvm::any_of(op->getOperandTypes(), 1089 [&](Type type) { return type != resultType; })) { 1090 p.printGenericOp(op); 1091 return; 1092 } 1093 1094 p << op->getName() << ' '; 1095 p.printOperands(op->getOperands()); 1096 p.printOptionalAttrDict(op->getAttrs()); 1097 // Now we can output only one type for all operands and the result. 1098 p << " : " << resultType; 1099 } 1100 1101 //===----------------------------------------------------------------------===// 1102 // CastOp implementation 1103 //===----------------------------------------------------------------------===// 1104 1105 void impl::buildCastOp(Builder *builder, OperationState &result, Value source, 1106 Type destType) { 1107 result.addOperands(source); 1108 result.addTypes(destType); 1109 } 1110 1111 ParseResult impl::parseCastOp(OpAsmParser &parser, OperationState &result) { 1112 OpAsmParser::OperandType srcInfo; 1113 Type srcType, dstType; 1114 return failure(parser.parseOperand(srcInfo) || 1115 parser.parseOptionalAttrDict(result.attributes) || 1116 parser.parseColonType(srcType) || 1117 parser.resolveOperand(srcInfo, srcType, result.operands) || 1118 parser.parseKeywordType("to", dstType) || 1119 parser.addTypeToList(dstType, result.types)); 1120 } 1121 1122 void impl::printCastOp(Operation *op, OpAsmPrinter &p) { 1123 p << op->getName() << ' ' << op->getOperand(0); 1124 p.printOptionalAttrDict(op->getAttrs()); 1125 p << " : " << op->getOperand(0).getType() << " to " 1126 << op->getResult(0).getType(); 1127 } 1128 1129 Value impl::foldCastOp(Operation *op) { 1130 // Identity cast 1131 if (op->getOperand(0).getType() == op->getResult(0).getType()) 1132 return op->getOperand(0); 1133 return nullptr; 1134 } 1135 1136 //===----------------------------------------------------------------------===// 1137 // Misc. utils 1138 //===----------------------------------------------------------------------===// 1139 1140 /// Insert an operation, generated by `buildTerminatorOp`, at the end of the 1141 /// region's only block if it does not have a terminator already. If the region 1142 /// is empty, insert a new block first. `buildTerminatorOp` should return the 1143 /// terminator operation to insert. 1144 void impl::ensureRegionTerminator( 1145 Region ®ion, Location loc, 1146 function_ref<Operation *()> buildTerminatorOp) { 1147 if (region.empty()) 1148 region.push_back(new Block); 1149 1150 Block &block = region.back(); 1151 if (!block.empty() && block.back().isKnownTerminator()) 1152 return; 1153 1154 block.push_back(buildTerminatorOp()); 1155 } 1156