1 //===- IR.cpp - C Interface for Core MLIR APIs ----------------------------===// 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-c/IR.h" 10 #include "mlir-c/Support.h" 11 12 #include "mlir/CAPI/IR.h" 13 #include "mlir/CAPI/Support.h" 14 #include "mlir/CAPI/Utils.h" 15 #include "mlir/IR/Attributes.h" 16 #include "mlir/IR/BuiltinOps.h" 17 #include "mlir/IR/Dialect.h" 18 #include "mlir/IR/Operation.h" 19 #include "mlir/IR/Types.h" 20 #include "mlir/IR/Verifier.h" 21 #include "mlir/Interfaces/InferTypeOpInterface.h" 22 #include "mlir/Parser.h" 23 24 using namespace mlir; 25 26 //===----------------------------------------------------------------------===// 27 // Context API. 28 //===----------------------------------------------------------------------===// 29 30 MlirContext mlirContextCreate() { 31 auto *context = new MLIRContext; 32 return wrap(context); 33 } 34 35 bool mlirContextEqual(MlirContext ctx1, MlirContext ctx2) { 36 return unwrap(ctx1) == unwrap(ctx2); 37 } 38 39 void mlirContextDestroy(MlirContext context) { delete unwrap(context); } 40 41 void mlirContextSetAllowUnregisteredDialects(MlirContext context, bool allow) { 42 unwrap(context)->allowUnregisteredDialects(allow); 43 } 44 45 bool mlirContextGetAllowUnregisteredDialects(MlirContext context) { 46 return unwrap(context)->allowsUnregisteredDialects(); 47 } 48 intptr_t mlirContextGetNumRegisteredDialects(MlirContext context) { 49 return static_cast<intptr_t>(unwrap(context)->getAvailableDialects().size()); 50 } 51 52 // TODO: expose a cheaper way than constructing + sorting a vector only to take 53 // its size. 54 intptr_t mlirContextGetNumLoadedDialects(MlirContext context) { 55 return static_cast<intptr_t>(unwrap(context)->getLoadedDialects().size()); 56 } 57 58 MlirDialect mlirContextGetOrLoadDialect(MlirContext context, 59 MlirStringRef name) { 60 return wrap(unwrap(context)->getOrLoadDialect(unwrap(name))); 61 } 62 63 //===----------------------------------------------------------------------===// 64 // Dialect API. 65 //===----------------------------------------------------------------------===// 66 67 MlirContext mlirDialectGetContext(MlirDialect dialect) { 68 return wrap(unwrap(dialect)->getContext()); 69 } 70 71 bool mlirDialectEqual(MlirDialect dialect1, MlirDialect dialect2) { 72 return unwrap(dialect1) == unwrap(dialect2); 73 } 74 75 MlirStringRef mlirDialectGetNamespace(MlirDialect dialect) { 76 return wrap(unwrap(dialect)->getNamespace()); 77 } 78 79 //===----------------------------------------------------------------------===// 80 // Printing flags API. 81 //===----------------------------------------------------------------------===// 82 83 MlirOpPrintingFlags mlirOpPrintingFlagsCreate() { 84 return wrap(new OpPrintingFlags()); 85 } 86 87 void mlirOpPrintingFlagsDestroy(MlirOpPrintingFlags flags) { 88 delete unwrap(flags); 89 } 90 91 void mlirOpPrintingFlagsElideLargeElementsAttrs(MlirOpPrintingFlags flags, 92 intptr_t largeElementLimit) { 93 unwrap(flags)->elideLargeElementsAttrs(largeElementLimit); 94 } 95 96 void mlirOpPrintingFlagsEnableDebugInfo(MlirOpPrintingFlags flags, 97 bool prettyForm) { 98 unwrap(flags)->enableDebugInfo(/*prettyForm=*/prettyForm); 99 } 100 101 void mlirOpPrintingFlagsPrintGenericOpForm(MlirOpPrintingFlags flags) { 102 unwrap(flags)->printGenericOpForm(); 103 } 104 105 void mlirOpPrintingFlagsUseLocalScope(MlirOpPrintingFlags flags) { 106 unwrap(flags)->useLocalScope(); 107 } 108 109 //===----------------------------------------------------------------------===// 110 // Location API. 111 //===----------------------------------------------------------------------===// 112 113 MlirLocation mlirLocationFileLineColGet(MlirContext context, 114 MlirStringRef filename, unsigned line, 115 unsigned col) { 116 return wrap( 117 FileLineColLoc::get(unwrap(filename), line, col, unwrap(context))); 118 } 119 120 MlirLocation mlirLocationCallSiteGet(MlirLocation callee, MlirLocation caller) { 121 return wrap(CallSiteLoc::get(unwrap(callee), unwrap(caller))); 122 } 123 124 MlirLocation mlirLocationUnknownGet(MlirContext context) { 125 return wrap(UnknownLoc::get(unwrap(context))); 126 } 127 128 bool mlirLocationEqual(MlirLocation l1, MlirLocation l2) { 129 return unwrap(l1) == unwrap(l2); 130 } 131 132 MlirContext mlirLocationGetContext(MlirLocation location) { 133 return wrap(unwrap(location).getContext()); 134 } 135 136 void mlirLocationPrint(MlirLocation location, MlirStringCallback callback, 137 void *userData) { 138 detail::CallbackOstream stream(callback, userData); 139 unwrap(location).print(stream); 140 } 141 142 //===----------------------------------------------------------------------===// 143 // Module API. 144 //===----------------------------------------------------------------------===// 145 146 MlirModule mlirModuleCreateEmpty(MlirLocation location) { 147 return wrap(ModuleOp::create(unwrap(location))); 148 } 149 150 MlirModule mlirModuleCreateParse(MlirContext context, MlirStringRef module) { 151 OwningModuleRef owning = parseSourceString(unwrap(module), unwrap(context)); 152 if (!owning) 153 return MlirModule{nullptr}; 154 return MlirModule{owning.release().getOperation()}; 155 } 156 157 MlirContext mlirModuleGetContext(MlirModule module) { 158 return wrap(unwrap(module).getContext()); 159 } 160 161 MlirBlock mlirModuleGetBody(MlirModule module) { 162 return wrap(unwrap(module).getBody()); 163 } 164 165 void mlirModuleDestroy(MlirModule module) { 166 // Transfer ownership to an OwningModuleRef so that its destructor is called. 167 OwningModuleRef(unwrap(module)); 168 } 169 170 MlirOperation mlirModuleGetOperation(MlirModule module) { 171 return wrap(unwrap(module).getOperation()); 172 } 173 174 //===----------------------------------------------------------------------===// 175 // Operation state API. 176 //===----------------------------------------------------------------------===// 177 178 MlirOperationState mlirOperationStateGet(MlirStringRef name, MlirLocation loc) { 179 MlirOperationState state; 180 state.name = name; 181 state.location = loc; 182 state.nResults = 0; 183 state.results = nullptr; 184 state.nOperands = 0; 185 state.operands = nullptr; 186 state.nRegions = 0; 187 state.regions = nullptr; 188 state.nSuccessors = 0; 189 state.successors = nullptr; 190 state.nAttributes = 0; 191 state.attributes = nullptr; 192 state.enableResultTypeInference = false; 193 return state; 194 } 195 196 #define APPEND_ELEMS(type, sizeName, elemName) \ 197 state->elemName = \ 198 (type *)realloc(state->elemName, (state->sizeName + n) * sizeof(type)); \ 199 memcpy(state->elemName + state->sizeName, elemName, n * sizeof(type)); \ 200 state->sizeName += n; 201 202 void mlirOperationStateAddResults(MlirOperationState *state, intptr_t n, 203 MlirType const *results) { 204 APPEND_ELEMS(MlirType, nResults, results); 205 } 206 207 void mlirOperationStateAddOperands(MlirOperationState *state, intptr_t n, 208 MlirValue const *operands) { 209 APPEND_ELEMS(MlirValue, nOperands, operands); 210 } 211 void mlirOperationStateAddOwnedRegions(MlirOperationState *state, intptr_t n, 212 MlirRegion const *regions) { 213 APPEND_ELEMS(MlirRegion, nRegions, regions); 214 } 215 void mlirOperationStateAddSuccessors(MlirOperationState *state, intptr_t n, 216 MlirBlock const *successors) { 217 APPEND_ELEMS(MlirBlock, nSuccessors, successors); 218 } 219 void mlirOperationStateAddAttributes(MlirOperationState *state, intptr_t n, 220 MlirNamedAttribute const *attributes) { 221 APPEND_ELEMS(MlirNamedAttribute, nAttributes, attributes); 222 } 223 224 void mlirOperationStateEnableResultTypeInference(MlirOperationState *state) { 225 state->enableResultTypeInference = true; 226 } 227 228 //===----------------------------------------------------------------------===// 229 // Operation API. 230 //===----------------------------------------------------------------------===// 231 232 static LogicalResult inferOperationTypes(OperationState &state) { 233 MLIRContext *context = state.getContext(); 234 const AbstractOperation *abstractOp = 235 AbstractOperation::lookup(state.name.getStringRef(), context); 236 if (!abstractOp) { 237 emitError(state.location) 238 << "type inference was requested for the operation " << state.name 239 << ", but the operation was not registered. Ensure that the dialect " 240 "containing the operation is linked into MLIR and registered with " 241 "the context"; 242 return failure(); 243 } 244 245 // Fallback to inference via an op interface. 246 auto *inferInterface = abstractOp->getInterface<InferTypeOpInterface>(); 247 if (!inferInterface) { 248 emitError(state.location) 249 << "type inference was requested for the operation " << state.name 250 << ", but the operation does not support type inference. Result " 251 "types must be specified explicitly."; 252 return failure(); 253 } 254 255 if (succeeded(inferInterface->inferReturnTypes( 256 context, state.location, state.operands, 257 state.attributes.getDictionary(context), state.regions, state.types))) 258 return success(); 259 260 // Diagnostic emitted by interface. 261 return failure(); 262 } 263 264 MlirOperation mlirOperationCreate(MlirOperationState *state) { 265 assert(state); 266 OperationState cppState(unwrap(state->location), unwrap(state->name)); 267 SmallVector<Type, 4> resultStorage; 268 SmallVector<Value, 8> operandStorage; 269 SmallVector<Block *, 2> successorStorage; 270 cppState.addTypes(unwrapList(state->nResults, state->results, resultStorage)); 271 cppState.addOperands( 272 unwrapList(state->nOperands, state->operands, operandStorage)); 273 cppState.addSuccessors( 274 unwrapList(state->nSuccessors, state->successors, successorStorage)); 275 276 cppState.attributes.reserve(state->nAttributes); 277 for (intptr_t i = 0; i < state->nAttributes; ++i) 278 cppState.addAttribute(unwrap(state->attributes[i].name), 279 unwrap(state->attributes[i].attribute)); 280 281 for (intptr_t i = 0; i < state->nRegions; ++i) 282 cppState.addRegion(std::unique_ptr<Region>(unwrap(state->regions[i]))); 283 284 free(state->results); 285 free(state->operands); 286 free(state->successors); 287 free(state->regions); 288 free(state->attributes); 289 290 // Infer result types. 291 if (state->enableResultTypeInference) { 292 assert(cppState.types.empty() && 293 "result type inference enabled and result types provided"); 294 if (failed(inferOperationTypes(cppState))) 295 return {nullptr}; 296 } 297 298 MlirOperation result = wrap(Operation::create(cppState)); 299 return result; 300 } 301 302 void mlirOperationDestroy(MlirOperation op) { unwrap(op)->erase(); } 303 304 bool mlirOperationEqual(MlirOperation op, MlirOperation other) { 305 return unwrap(op) == unwrap(other); 306 } 307 308 MlirIdentifier mlirOperationGetName(MlirOperation op) { 309 return wrap(unwrap(op)->getName().getIdentifier()); 310 } 311 312 MlirBlock mlirOperationGetBlock(MlirOperation op) { 313 return wrap(unwrap(op)->getBlock()); 314 } 315 316 MlirOperation mlirOperationGetParentOperation(MlirOperation op) { 317 return wrap(unwrap(op)->getParentOp()); 318 } 319 320 intptr_t mlirOperationGetNumRegions(MlirOperation op) { 321 return static_cast<intptr_t>(unwrap(op)->getNumRegions()); 322 } 323 324 MlirRegion mlirOperationGetRegion(MlirOperation op, intptr_t pos) { 325 return wrap(&unwrap(op)->getRegion(static_cast<unsigned>(pos))); 326 } 327 328 MlirOperation mlirOperationGetNextInBlock(MlirOperation op) { 329 return wrap(unwrap(op)->getNextNode()); 330 } 331 332 intptr_t mlirOperationGetNumOperands(MlirOperation op) { 333 return static_cast<intptr_t>(unwrap(op)->getNumOperands()); 334 } 335 336 MlirValue mlirOperationGetOperand(MlirOperation op, intptr_t pos) { 337 return wrap(unwrap(op)->getOperand(static_cast<unsigned>(pos))); 338 } 339 340 intptr_t mlirOperationGetNumResults(MlirOperation op) { 341 return static_cast<intptr_t>(unwrap(op)->getNumResults()); 342 } 343 344 MlirValue mlirOperationGetResult(MlirOperation op, intptr_t pos) { 345 return wrap(unwrap(op)->getResult(static_cast<unsigned>(pos))); 346 } 347 348 intptr_t mlirOperationGetNumSuccessors(MlirOperation op) { 349 return static_cast<intptr_t>(unwrap(op)->getNumSuccessors()); 350 } 351 352 MlirBlock mlirOperationGetSuccessor(MlirOperation op, intptr_t pos) { 353 return wrap(unwrap(op)->getSuccessor(static_cast<unsigned>(pos))); 354 } 355 356 intptr_t mlirOperationGetNumAttributes(MlirOperation op) { 357 return static_cast<intptr_t>(unwrap(op)->getAttrs().size()); 358 } 359 360 MlirNamedAttribute mlirOperationGetAttribute(MlirOperation op, intptr_t pos) { 361 NamedAttribute attr = unwrap(op)->getAttrs()[pos]; 362 return MlirNamedAttribute{wrap(attr.first), wrap(attr.second)}; 363 } 364 365 MlirAttribute mlirOperationGetAttributeByName(MlirOperation op, 366 MlirStringRef name) { 367 return wrap(unwrap(op)->getAttr(unwrap(name))); 368 } 369 370 void mlirOperationSetAttributeByName(MlirOperation op, MlirStringRef name, 371 MlirAttribute attr) { 372 unwrap(op)->setAttr(unwrap(name), unwrap(attr)); 373 } 374 375 bool mlirOperationRemoveAttributeByName(MlirOperation op, MlirStringRef name) { 376 return !!unwrap(op)->removeAttr(unwrap(name)); 377 } 378 379 void mlirOperationPrint(MlirOperation op, MlirStringCallback callback, 380 void *userData) { 381 detail::CallbackOstream stream(callback, userData); 382 unwrap(op)->print(stream); 383 } 384 385 void mlirOperationPrintWithFlags(MlirOperation op, MlirOpPrintingFlags flags, 386 MlirStringCallback callback, void *userData) { 387 detail::CallbackOstream stream(callback, userData); 388 unwrap(op)->print(stream, *unwrap(flags)); 389 } 390 391 void mlirOperationDump(MlirOperation op) { return unwrap(op)->dump(); } 392 393 bool mlirOperationVerify(MlirOperation op) { 394 return succeeded(verify(unwrap(op))); 395 } 396 397 //===----------------------------------------------------------------------===// 398 // Region API. 399 //===----------------------------------------------------------------------===// 400 401 MlirRegion mlirRegionCreate() { return wrap(new Region); } 402 403 MlirBlock mlirRegionGetFirstBlock(MlirRegion region) { 404 Region *cppRegion = unwrap(region); 405 if (cppRegion->empty()) 406 return wrap(static_cast<Block *>(nullptr)); 407 return wrap(&cppRegion->front()); 408 } 409 410 void mlirRegionAppendOwnedBlock(MlirRegion region, MlirBlock block) { 411 unwrap(region)->push_back(unwrap(block)); 412 } 413 414 void mlirRegionInsertOwnedBlock(MlirRegion region, intptr_t pos, 415 MlirBlock block) { 416 auto &blockList = unwrap(region)->getBlocks(); 417 blockList.insert(std::next(blockList.begin(), pos), unwrap(block)); 418 } 419 420 void mlirRegionInsertOwnedBlockAfter(MlirRegion region, MlirBlock reference, 421 MlirBlock block) { 422 Region *cppRegion = unwrap(region); 423 if (mlirBlockIsNull(reference)) { 424 cppRegion->getBlocks().insert(cppRegion->begin(), unwrap(block)); 425 return; 426 } 427 428 assert(unwrap(reference)->getParent() == unwrap(region) && 429 "expected reference block to belong to the region"); 430 cppRegion->getBlocks().insertAfter(Region::iterator(unwrap(reference)), 431 unwrap(block)); 432 } 433 434 void mlirRegionInsertOwnedBlockBefore(MlirRegion region, MlirBlock reference, 435 MlirBlock block) { 436 if (mlirBlockIsNull(reference)) 437 return mlirRegionAppendOwnedBlock(region, block); 438 439 assert(unwrap(reference)->getParent() == unwrap(region) && 440 "expected reference block to belong to the region"); 441 unwrap(region)->getBlocks().insert(Region::iterator(unwrap(reference)), 442 unwrap(block)); 443 } 444 445 void mlirRegionDestroy(MlirRegion region) { 446 delete static_cast<Region *>(region.ptr); 447 } 448 449 //===----------------------------------------------------------------------===// 450 // Block API. 451 //===----------------------------------------------------------------------===// 452 453 MlirBlock mlirBlockCreate(intptr_t nArgs, MlirType const *args) { 454 Block *b = new Block; 455 for (intptr_t i = 0; i < nArgs; ++i) 456 b->addArgument(unwrap(args[i])); 457 return wrap(b); 458 } 459 460 bool mlirBlockEqual(MlirBlock block, MlirBlock other) { 461 return unwrap(block) == unwrap(other); 462 } 463 464 MlirBlock mlirBlockGetNextInRegion(MlirBlock block) { 465 return wrap(unwrap(block)->getNextNode()); 466 } 467 468 MlirOperation mlirBlockGetFirstOperation(MlirBlock block) { 469 Block *cppBlock = unwrap(block); 470 if (cppBlock->empty()) 471 return wrap(static_cast<Operation *>(nullptr)); 472 return wrap(&cppBlock->front()); 473 } 474 475 MlirOperation mlirBlockGetTerminator(MlirBlock block) { 476 Block *cppBlock = unwrap(block); 477 if (cppBlock->empty()) 478 return wrap(static_cast<Operation *>(nullptr)); 479 Operation &back = cppBlock->back(); 480 if (!back.isKnownTerminator()) 481 return wrap(static_cast<Operation *>(nullptr)); 482 return wrap(&back); 483 } 484 485 void mlirBlockAppendOwnedOperation(MlirBlock block, MlirOperation operation) { 486 unwrap(block)->push_back(unwrap(operation)); 487 } 488 489 void mlirBlockInsertOwnedOperation(MlirBlock block, intptr_t pos, 490 MlirOperation operation) { 491 auto &opList = unwrap(block)->getOperations(); 492 opList.insert(std::next(opList.begin(), pos), unwrap(operation)); 493 } 494 495 void mlirBlockInsertOwnedOperationAfter(MlirBlock block, 496 MlirOperation reference, 497 MlirOperation operation) { 498 Block *cppBlock = unwrap(block); 499 if (mlirOperationIsNull(reference)) { 500 cppBlock->getOperations().insert(cppBlock->begin(), unwrap(operation)); 501 return; 502 } 503 504 assert(unwrap(reference)->getBlock() == unwrap(block) && 505 "expected reference operation to belong to the block"); 506 cppBlock->getOperations().insertAfter(Block::iterator(unwrap(reference)), 507 unwrap(operation)); 508 } 509 510 void mlirBlockInsertOwnedOperationBefore(MlirBlock block, 511 MlirOperation reference, 512 MlirOperation operation) { 513 if (mlirOperationIsNull(reference)) 514 return mlirBlockAppendOwnedOperation(block, operation); 515 516 assert(unwrap(reference)->getBlock() == unwrap(block) && 517 "expected reference operation to belong to the block"); 518 unwrap(block)->getOperations().insert(Block::iterator(unwrap(reference)), 519 unwrap(operation)); 520 } 521 522 void mlirBlockDestroy(MlirBlock block) { delete unwrap(block); } 523 524 intptr_t mlirBlockGetNumArguments(MlirBlock block) { 525 return static_cast<intptr_t>(unwrap(block)->getNumArguments()); 526 } 527 528 MlirValue mlirBlockGetArgument(MlirBlock block, intptr_t pos) { 529 return wrap(unwrap(block)->getArgument(static_cast<unsigned>(pos))); 530 } 531 532 void mlirBlockPrint(MlirBlock block, MlirStringCallback callback, 533 void *userData) { 534 detail::CallbackOstream stream(callback, userData); 535 unwrap(block)->print(stream); 536 } 537 538 //===----------------------------------------------------------------------===// 539 // Value API. 540 //===----------------------------------------------------------------------===// 541 542 bool mlirValueEqual(MlirValue value1, MlirValue value2) { 543 return unwrap(value1) == unwrap(value2); 544 } 545 546 bool mlirValueIsABlockArgument(MlirValue value) { 547 return unwrap(value).isa<BlockArgument>(); 548 } 549 550 bool mlirValueIsAOpResult(MlirValue value) { 551 return unwrap(value).isa<OpResult>(); 552 } 553 554 MlirBlock mlirBlockArgumentGetOwner(MlirValue value) { 555 return wrap(unwrap(value).cast<BlockArgument>().getOwner()); 556 } 557 558 intptr_t mlirBlockArgumentGetArgNumber(MlirValue value) { 559 return static_cast<intptr_t>( 560 unwrap(value).cast<BlockArgument>().getArgNumber()); 561 } 562 563 void mlirBlockArgumentSetType(MlirValue value, MlirType type) { 564 unwrap(value).cast<BlockArgument>().setType(unwrap(type)); 565 } 566 567 MlirOperation mlirOpResultGetOwner(MlirValue value) { 568 return wrap(unwrap(value).cast<OpResult>().getOwner()); 569 } 570 571 intptr_t mlirOpResultGetResultNumber(MlirValue value) { 572 return static_cast<intptr_t>( 573 unwrap(value).cast<OpResult>().getResultNumber()); 574 } 575 576 MlirType mlirValueGetType(MlirValue value) { 577 return wrap(unwrap(value).getType()); 578 } 579 580 void mlirValueDump(MlirValue value) { unwrap(value).dump(); } 581 582 void mlirValuePrint(MlirValue value, MlirStringCallback callback, 583 void *userData) { 584 detail::CallbackOstream stream(callback, userData); 585 unwrap(value).print(stream); 586 } 587 588 //===----------------------------------------------------------------------===// 589 // Type API. 590 //===----------------------------------------------------------------------===// 591 592 MlirType mlirTypeParseGet(MlirContext context, MlirStringRef type) { 593 return wrap(mlir::parseType(unwrap(type), unwrap(context))); 594 } 595 596 MlirContext mlirTypeGetContext(MlirType type) { 597 return wrap(unwrap(type).getContext()); 598 } 599 600 bool mlirTypeEqual(MlirType t1, MlirType t2) { 601 return unwrap(t1) == unwrap(t2); 602 } 603 604 void mlirTypePrint(MlirType type, MlirStringCallback callback, void *userData) { 605 detail::CallbackOstream stream(callback, userData); 606 unwrap(type).print(stream); 607 } 608 609 void mlirTypeDump(MlirType type) { unwrap(type).dump(); } 610 611 //===----------------------------------------------------------------------===// 612 // Attribute API. 613 //===----------------------------------------------------------------------===// 614 615 MlirAttribute mlirAttributeParseGet(MlirContext context, MlirStringRef attr) { 616 return wrap(mlir::parseAttribute(unwrap(attr), unwrap(context))); 617 } 618 619 MlirContext mlirAttributeGetContext(MlirAttribute attribute) { 620 return wrap(unwrap(attribute).getContext()); 621 } 622 623 MlirType mlirAttributeGetType(MlirAttribute attribute) { 624 return wrap(unwrap(attribute).getType()); 625 } 626 627 bool mlirAttributeEqual(MlirAttribute a1, MlirAttribute a2) { 628 return unwrap(a1) == unwrap(a2); 629 } 630 631 void mlirAttributePrint(MlirAttribute attr, MlirStringCallback callback, 632 void *userData) { 633 detail::CallbackOstream stream(callback, userData); 634 unwrap(attr).print(stream); 635 } 636 637 void mlirAttributeDump(MlirAttribute attr) { unwrap(attr).dump(); } 638 639 MlirNamedAttribute mlirNamedAttributeGet(MlirIdentifier name, 640 MlirAttribute attr) { 641 return MlirNamedAttribute{name, attr}; 642 } 643 644 //===----------------------------------------------------------------------===// 645 // Identifier API. 646 //===----------------------------------------------------------------------===// 647 648 MlirIdentifier mlirIdentifierGet(MlirContext context, MlirStringRef str) { 649 return wrap(Identifier::get(unwrap(str), unwrap(context))); 650 } 651 652 bool mlirIdentifierEqual(MlirIdentifier ident, MlirIdentifier other) { 653 return unwrap(ident) == unwrap(other); 654 } 655 656 MlirStringRef mlirIdentifierStr(MlirIdentifier ident) { 657 return wrap(unwrap(ident).strref()); 658 } 659