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(Location( 117 FileLineColLoc::get(unwrap(context), unwrap(filename), line, col))); 118 } 119 120 MlirLocation mlirLocationCallSiteGet(MlirLocation callee, MlirLocation caller) { 121 return wrap(Location(CallSiteLoc::get(unwrap(callee), unwrap(caller)))); 122 } 123 124 MlirLocation mlirLocationUnknownGet(MlirContext context) { 125 return wrap(Location(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 MlirContext mlirOperationGetContext(MlirOperation op) { 309 return wrap(unwrap(op)->getContext()); 310 } 311 312 MlirIdentifier mlirOperationGetName(MlirOperation op) { 313 return wrap(unwrap(op)->getName().getIdentifier()); 314 } 315 316 MlirBlock mlirOperationGetBlock(MlirOperation op) { 317 return wrap(unwrap(op)->getBlock()); 318 } 319 320 MlirOperation mlirOperationGetParentOperation(MlirOperation op) { 321 return wrap(unwrap(op)->getParentOp()); 322 } 323 324 intptr_t mlirOperationGetNumRegions(MlirOperation op) { 325 return static_cast<intptr_t>(unwrap(op)->getNumRegions()); 326 } 327 328 MlirRegion mlirOperationGetRegion(MlirOperation op, intptr_t pos) { 329 return wrap(&unwrap(op)->getRegion(static_cast<unsigned>(pos))); 330 } 331 332 MlirOperation mlirOperationGetNextInBlock(MlirOperation op) { 333 return wrap(unwrap(op)->getNextNode()); 334 } 335 336 intptr_t mlirOperationGetNumOperands(MlirOperation op) { 337 return static_cast<intptr_t>(unwrap(op)->getNumOperands()); 338 } 339 340 MlirValue mlirOperationGetOperand(MlirOperation op, intptr_t pos) { 341 return wrap(unwrap(op)->getOperand(static_cast<unsigned>(pos))); 342 } 343 344 intptr_t mlirOperationGetNumResults(MlirOperation op) { 345 return static_cast<intptr_t>(unwrap(op)->getNumResults()); 346 } 347 348 MlirValue mlirOperationGetResult(MlirOperation op, intptr_t pos) { 349 return wrap(unwrap(op)->getResult(static_cast<unsigned>(pos))); 350 } 351 352 intptr_t mlirOperationGetNumSuccessors(MlirOperation op) { 353 return static_cast<intptr_t>(unwrap(op)->getNumSuccessors()); 354 } 355 356 MlirBlock mlirOperationGetSuccessor(MlirOperation op, intptr_t pos) { 357 return wrap(unwrap(op)->getSuccessor(static_cast<unsigned>(pos))); 358 } 359 360 intptr_t mlirOperationGetNumAttributes(MlirOperation op) { 361 return static_cast<intptr_t>(unwrap(op)->getAttrs().size()); 362 } 363 364 MlirNamedAttribute mlirOperationGetAttribute(MlirOperation op, intptr_t pos) { 365 NamedAttribute attr = unwrap(op)->getAttrs()[pos]; 366 return MlirNamedAttribute{wrap(attr.first), wrap(attr.second)}; 367 } 368 369 MlirAttribute mlirOperationGetAttributeByName(MlirOperation op, 370 MlirStringRef name) { 371 return wrap(unwrap(op)->getAttr(unwrap(name))); 372 } 373 374 void mlirOperationSetAttributeByName(MlirOperation op, MlirStringRef name, 375 MlirAttribute attr) { 376 unwrap(op)->setAttr(unwrap(name), unwrap(attr)); 377 } 378 379 bool mlirOperationRemoveAttributeByName(MlirOperation op, MlirStringRef name) { 380 return !!unwrap(op)->removeAttr(unwrap(name)); 381 } 382 383 void mlirOperationPrint(MlirOperation op, MlirStringCallback callback, 384 void *userData) { 385 detail::CallbackOstream stream(callback, userData); 386 unwrap(op)->print(stream); 387 } 388 389 void mlirOperationPrintWithFlags(MlirOperation op, MlirOpPrintingFlags flags, 390 MlirStringCallback callback, void *userData) { 391 detail::CallbackOstream stream(callback, userData); 392 unwrap(op)->print(stream, *unwrap(flags)); 393 } 394 395 void mlirOperationDump(MlirOperation op) { return unwrap(op)->dump(); } 396 397 bool mlirOperationVerify(MlirOperation op) { 398 return succeeded(verify(unwrap(op))); 399 } 400 401 //===----------------------------------------------------------------------===// 402 // Region API. 403 //===----------------------------------------------------------------------===// 404 405 MlirRegion mlirRegionCreate() { return wrap(new Region); } 406 407 MlirBlock mlirRegionGetFirstBlock(MlirRegion region) { 408 Region *cppRegion = unwrap(region); 409 if (cppRegion->empty()) 410 return wrap(static_cast<Block *>(nullptr)); 411 return wrap(&cppRegion->front()); 412 } 413 414 void mlirRegionAppendOwnedBlock(MlirRegion region, MlirBlock block) { 415 unwrap(region)->push_back(unwrap(block)); 416 } 417 418 void mlirRegionInsertOwnedBlock(MlirRegion region, intptr_t pos, 419 MlirBlock block) { 420 auto &blockList = unwrap(region)->getBlocks(); 421 blockList.insert(std::next(blockList.begin(), pos), unwrap(block)); 422 } 423 424 void mlirRegionInsertOwnedBlockAfter(MlirRegion region, MlirBlock reference, 425 MlirBlock block) { 426 Region *cppRegion = unwrap(region); 427 if (mlirBlockIsNull(reference)) { 428 cppRegion->getBlocks().insert(cppRegion->begin(), unwrap(block)); 429 return; 430 } 431 432 assert(unwrap(reference)->getParent() == unwrap(region) && 433 "expected reference block to belong to the region"); 434 cppRegion->getBlocks().insertAfter(Region::iterator(unwrap(reference)), 435 unwrap(block)); 436 } 437 438 void mlirRegionInsertOwnedBlockBefore(MlirRegion region, MlirBlock reference, 439 MlirBlock block) { 440 if (mlirBlockIsNull(reference)) 441 return mlirRegionAppendOwnedBlock(region, block); 442 443 assert(unwrap(reference)->getParent() == unwrap(region) && 444 "expected reference block to belong to the region"); 445 unwrap(region)->getBlocks().insert(Region::iterator(unwrap(reference)), 446 unwrap(block)); 447 } 448 449 void mlirRegionDestroy(MlirRegion region) { 450 delete static_cast<Region *>(region.ptr); 451 } 452 453 //===----------------------------------------------------------------------===// 454 // Block API. 455 //===----------------------------------------------------------------------===// 456 457 MlirBlock mlirBlockCreate(intptr_t nArgs, MlirType const *args) { 458 Block *b = new Block; 459 for (intptr_t i = 0; i < nArgs; ++i) 460 b->addArgument(unwrap(args[i])); 461 return wrap(b); 462 } 463 464 bool mlirBlockEqual(MlirBlock block, MlirBlock other) { 465 return unwrap(block) == unwrap(other); 466 } 467 468 MlirOperation mlirBlockGetParentOperation(MlirBlock block) { 469 return wrap(unwrap(block)->getParentOp()); 470 } 471 472 MlirBlock mlirBlockGetNextInRegion(MlirBlock block) { 473 return wrap(unwrap(block)->getNextNode()); 474 } 475 476 MlirOperation mlirBlockGetFirstOperation(MlirBlock block) { 477 Block *cppBlock = unwrap(block); 478 if (cppBlock->empty()) 479 return wrap(static_cast<Operation *>(nullptr)); 480 return wrap(&cppBlock->front()); 481 } 482 483 MlirOperation mlirBlockGetTerminator(MlirBlock block) { 484 Block *cppBlock = unwrap(block); 485 if (cppBlock->empty()) 486 return wrap(static_cast<Operation *>(nullptr)); 487 Operation &back = cppBlock->back(); 488 if (!back.hasTrait<OpTrait::IsTerminator>()) 489 return wrap(static_cast<Operation *>(nullptr)); 490 return wrap(&back); 491 } 492 493 void mlirBlockAppendOwnedOperation(MlirBlock block, MlirOperation operation) { 494 unwrap(block)->push_back(unwrap(operation)); 495 } 496 497 void mlirBlockInsertOwnedOperation(MlirBlock block, intptr_t pos, 498 MlirOperation operation) { 499 auto &opList = unwrap(block)->getOperations(); 500 opList.insert(std::next(opList.begin(), pos), unwrap(operation)); 501 } 502 503 void mlirBlockInsertOwnedOperationAfter(MlirBlock block, 504 MlirOperation reference, 505 MlirOperation operation) { 506 Block *cppBlock = unwrap(block); 507 if (mlirOperationIsNull(reference)) { 508 cppBlock->getOperations().insert(cppBlock->begin(), unwrap(operation)); 509 return; 510 } 511 512 assert(unwrap(reference)->getBlock() == unwrap(block) && 513 "expected reference operation to belong to the block"); 514 cppBlock->getOperations().insertAfter(Block::iterator(unwrap(reference)), 515 unwrap(operation)); 516 } 517 518 void mlirBlockInsertOwnedOperationBefore(MlirBlock block, 519 MlirOperation reference, 520 MlirOperation operation) { 521 if (mlirOperationIsNull(reference)) 522 return mlirBlockAppendOwnedOperation(block, operation); 523 524 assert(unwrap(reference)->getBlock() == unwrap(block) && 525 "expected reference operation to belong to the block"); 526 unwrap(block)->getOperations().insert(Block::iterator(unwrap(reference)), 527 unwrap(operation)); 528 } 529 530 void mlirBlockDestroy(MlirBlock block) { delete unwrap(block); } 531 532 intptr_t mlirBlockGetNumArguments(MlirBlock block) { 533 return static_cast<intptr_t>(unwrap(block)->getNumArguments()); 534 } 535 536 MlirValue mlirBlockAddArgument(MlirBlock block, MlirType type) { 537 return wrap(unwrap(block)->addArgument(unwrap(type))); 538 } 539 540 MlirValue mlirBlockGetArgument(MlirBlock block, intptr_t pos) { 541 return wrap(unwrap(block)->getArgument(static_cast<unsigned>(pos))); 542 } 543 544 void mlirBlockPrint(MlirBlock block, MlirStringCallback callback, 545 void *userData) { 546 detail::CallbackOstream stream(callback, userData); 547 unwrap(block)->print(stream); 548 } 549 550 //===----------------------------------------------------------------------===// 551 // Value API. 552 //===----------------------------------------------------------------------===// 553 554 bool mlirValueEqual(MlirValue value1, MlirValue value2) { 555 return unwrap(value1) == unwrap(value2); 556 } 557 558 bool mlirValueIsABlockArgument(MlirValue value) { 559 return unwrap(value).isa<BlockArgument>(); 560 } 561 562 bool mlirValueIsAOpResult(MlirValue value) { 563 return unwrap(value).isa<OpResult>(); 564 } 565 566 MlirBlock mlirBlockArgumentGetOwner(MlirValue value) { 567 return wrap(unwrap(value).cast<BlockArgument>().getOwner()); 568 } 569 570 intptr_t mlirBlockArgumentGetArgNumber(MlirValue value) { 571 return static_cast<intptr_t>( 572 unwrap(value).cast<BlockArgument>().getArgNumber()); 573 } 574 575 void mlirBlockArgumentSetType(MlirValue value, MlirType type) { 576 unwrap(value).cast<BlockArgument>().setType(unwrap(type)); 577 } 578 579 MlirOperation mlirOpResultGetOwner(MlirValue value) { 580 return wrap(unwrap(value).cast<OpResult>().getOwner()); 581 } 582 583 intptr_t mlirOpResultGetResultNumber(MlirValue value) { 584 return static_cast<intptr_t>( 585 unwrap(value).cast<OpResult>().getResultNumber()); 586 } 587 588 MlirType mlirValueGetType(MlirValue value) { 589 return wrap(unwrap(value).getType()); 590 } 591 592 void mlirValueDump(MlirValue value) { unwrap(value).dump(); } 593 594 void mlirValuePrint(MlirValue value, MlirStringCallback callback, 595 void *userData) { 596 detail::CallbackOstream stream(callback, userData); 597 unwrap(value).print(stream); 598 } 599 600 //===----------------------------------------------------------------------===// 601 // Type API. 602 //===----------------------------------------------------------------------===// 603 604 MlirType mlirTypeParseGet(MlirContext context, MlirStringRef type) { 605 return wrap(mlir::parseType(unwrap(type), unwrap(context))); 606 } 607 608 MlirContext mlirTypeGetContext(MlirType type) { 609 return wrap(unwrap(type).getContext()); 610 } 611 612 bool mlirTypeEqual(MlirType t1, MlirType t2) { 613 return unwrap(t1) == unwrap(t2); 614 } 615 616 void mlirTypePrint(MlirType type, MlirStringCallback callback, void *userData) { 617 detail::CallbackOstream stream(callback, userData); 618 unwrap(type).print(stream); 619 } 620 621 void mlirTypeDump(MlirType type) { unwrap(type).dump(); } 622 623 //===----------------------------------------------------------------------===// 624 // Attribute API. 625 //===----------------------------------------------------------------------===// 626 627 MlirAttribute mlirAttributeParseGet(MlirContext context, MlirStringRef attr) { 628 return wrap(mlir::parseAttribute(unwrap(attr), unwrap(context))); 629 } 630 631 MlirContext mlirAttributeGetContext(MlirAttribute attribute) { 632 return wrap(unwrap(attribute).getContext()); 633 } 634 635 MlirType mlirAttributeGetType(MlirAttribute attribute) { 636 return wrap(unwrap(attribute).getType()); 637 } 638 639 bool mlirAttributeEqual(MlirAttribute a1, MlirAttribute a2) { 640 return unwrap(a1) == unwrap(a2); 641 } 642 643 void mlirAttributePrint(MlirAttribute attr, MlirStringCallback callback, 644 void *userData) { 645 detail::CallbackOstream stream(callback, userData); 646 unwrap(attr).print(stream); 647 } 648 649 void mlirAttributeDump(MlirAttribute attr) { unwrap(attr).dump(); } 650 651 MlirNamedAttribute mlirNamedAttributeGet(MlirIdentifier name, 652 MlirAttribute attr) { 653 return MlirNamedAttribute{name, attr}; 654 } 655 656 //===----------------------------------------------------------------------===// 657 // Identifier API. 658 //===----------------------------------------------------------------------===// 659 660 MlirIdentifier mlirIdentifierGet(MlirContext context, MlirStringRef str) { 661 return wrap(Identifier::get(unwrap(str), unwrap(context))); 662 } 663 664 MlirContext mlirIdentifierGetContext(MlirIdentifier ident) { 665 return wrap(unwrap(ident).getContext()); 666 } 667 668 bool mlirIdentifierEqual(MlirIdentifier ident, MlirIdentifier other) { 669 return unwrap(ident) == unwrap(other); 670 } 671 672 MlirStringRef mlirIdentifierStr(MlirIdentifier ident) { 673 return wrap(unwrap(ident).strref()); 674 } 675