1 //===- ir.c - Simple test of C APIs ---------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM 4 // Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 /* RUN: mlir-capi-ir-test 2>&1 | FileCheck %s 11 */ 12 13 #include "mlir-c/IR.h" 14 #include "mlir-c/AffineExpr.h" 15 #include "mlir-c/AffineMap.h" 16 #include "mlir-c/BuiltinAttributes.h" 17 #include "mlir-c/BuiltinTypes.h" 18 #include "mlir-c/Diagnostics.h" 19 #include "mlir-c/Dialect/Standard.h" 20 #include "mlir-c/IntegerSet.h" 21 #include "mlir-c/Registration.h" 22 #include "mlir-c/Support.h" 23 24 #include <assert.h> 25 #include <inttypes.h> 26 #include <math.h> 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 31 void populateLoopBody(MlirContext ctx, MlirBlock loopBody, 32 MlirLocation location, MlirBlock funcBody) { 33 MlirValue iv = mlirBlockGetArgument(loopBody, 0); 34 MlirValue funcArg0 = mlirBlockGetArgument(funcBody, 0); 35 MlirValue funcArg1 = mlirBlockGetArgument(funcBody, 1); 36 MlirType f32Type = 37 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("f32")); 38 39 MlirOperationState loadLHSState = mlirOperationStateGet( 40 mlirStringRefCreateFromCString("memref.load"), location); 41 MlirValue loadLHSOperands[] = {funcArg0, iv}; 42 mlirOperationStateAddOperands(&loadLHSState, 2, loadLHSOperands); 43 mlirOperationStateAddResults(&loadLHSState, 1, &f32Type); 44 MlirOperation loadLHS = mlirOperationCreate(&loadLHSState); 45 mlirBlockAppendOwnedOperation(loopBody, loadLHS); 46 47 MlirOperationState loadRHSState = mlirOperationStateGet( 48 mlirStringRefCreateFromCString("memref.load"), location); 49 MlirValue loadRHSOperands[] = {funcArg1, iv}; 50 mlirOperationStateAddOperands(&loadRHSState, 2, loadRHSOperands); 51 mlirOperationStateAddResults(&loadRHSState, 1, &f32Type); 52 MlirOperation loadRHS = mlirOperationCreate(&loadRHSState); 53 mlirBlockAppendOwnedOperation(loopBody, loadRHS); 54 55 MlirOperationState addState = mlirOperationStateGet( 56 mlirStringRefCreateFromCString("arith.addf"), location); 57 MlirValue addOperands[] = {mlirOperationGetResult(loadLHS, 0), 58 mlirOperationGetResult(loadRHS, 0)}; 59 mlirOperationStateAddOperands(&addState, 2, addOperands); 60 mlirOperationStateAddResults(&addState, 1, &f32Type); 61 MlirOperation add = mlirOperationCreate(&addState); 62 mlirBlockAppendOwnedOperation(loopBody, add); 63 64 MlirOperationState storeState = mlirOperationStateGet( 65 mlirStringRefCreateFromCString("memref.store"), location); 66 MlirValue storeOperands[] = {mlirOperationGetResult(add, 0), funcArg0, iv}; 67 mlirOperationStateAddOperands(&storeState, 3, storeOperands); 68 MlirOperation store = mlirOperationCreate(&storeState); 69 mlirBlockAppendOwnedOperation(loopBody, store); 70 71 MlirOperationState yieldState = mlirOperationStateGet( 72 mlirStringRefCreateFromCString("scf.yield"), location); 73 MlirOperation yield = mlirOperationCreate(&yieldState); 74 mlirBlockAppendOwnedOperation(loopBody, yield); 75 } 76 77 MlirModule makeAndDumpAdd(MlirContext ctx, MlirLocation location) { 78 MlirModule moduleOp = mlirModuleCreateEmpty(location); 79 MlirBlock moduleBody = mlirModuleGetBody(moduleOp); 80 81 MlirType memrefType = 82 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("memref<?xf32>")); 83 MlirType funcBodyArgTypes[] = {memrefType, memrefType}; 84 MlirRegion funcBodyRegion = mlirRegionCreate(); 85 MlirBlock funcBody = mlirBlockCreate( 86 sizeof(funcBodyArgTypes) / sizeof(MlirType), funcBodyArgTypes); 87 mlirRegionAppendOwnedBlock(funcBodyRegion, funcBody); 88 89 MlirAttribute funcTypeAttr = mlirAttributeParseGet( 90 ctx, 91 mlirStringRefCreateFromCString("(memref<?xf32>, memref<?xf32>) -> ()")); 92 MlirAttribute funcNameAttr = 93 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("\"add\"")); 94 MlirNamedAttribute funcAttrs[] = { 95 mlirNamedAttributeGet( 96 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("type")), 97 funcTypeAttr), 98 mlirNamedAttributeGet( 99 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("sym_name")), 100 funcNameAttr)}; 101 MlirOperationState funcState = mlirOperationStateGet( 102 mlirStringRefCreateFromCString("builtin.func"), location); 103 mlirOperationStateAddAttributes(&funcState, 2, funcAttrs); 104 mlirOperationStateAddOwnedRegions(&funcState, 1, &funcBodyRegion); 105 MlirOperation func = mlirOperationCreate(&funcState); 106 mlirBlockInsertOwnedOperation(moduleBody, 0, func); 107 108 MlirType indexType = 109 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("index")); 110 MlirAttribute indexZeroLiteral = 111 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 112 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 113 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 114 indexZeroLiteral); 115 MlirOperationState constZeroState = mlirOperationStateGet( 116 mlirStringRefCreateFromCString("arith.constant"), location); 117 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 118 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 119 MlirOperation constZero = mlirOperationCreate(&constZeroState); 120 mlirBlockAppendOwnedOperation(funcBody, constZero); 121 122 MlirValue funcArg0 = mlirBlockGetArgument(funcBody, 0); 123 MlirValue constZeroValue = mlirOperationGetResult(constZero, 0); 124 MlirValue dimOperands[] = {funcArg0, constZeroValue}; 125 MlirOperationState dimState = mlirOperationStateGet( 126 mlirStringRefCreateFromCString("memref.dim"), location); 127 mlirOperationStateAddOperands(&dimState, 2, dimOperands); 128 mlirOperationStateAddResults(&dimState, 1, &indexType); 129 MlirOperation dim = mlirOperationCreate(&dimState); 130 mlirBlockAppendOwnedOperation(funcBody, dim); 131 132 MlirRegion loopBodyRegion = mlirRegionCreate(); 133 MlirBlock loopBody = mlirBlockCreate(0, NULL); 134 mlirBlockAddArgument(loopBody, indexType); 135 mlirRegionAppendOwnedBlock(loopBodyRegion, loopBody); 136 137 MlirAttribute indexOneLiteral = 138 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index")); 139 MlirNamedAttribute indexOneValueAttr = mlirNamedAttributeGet( 140 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 141 indexOneLiteral); 142 MlirOperationState constOneState = mlirOperationStateGet( 143 mlirStringRefCreateFromCString("arith.constant"), location); 144 mlirOperationStateAddResults(&constOneState, 1, &indexType); 145 mlirOperationStateAddAttributes(&constOneState, 1, &indexOneValueAttr); 146 MlirOperation constOne = mlirOperationCreate(&constOneState); 147 mlirBlockAppendOwnedOperation(funcBody, constOne); 148 149 MlirValue dimValue = mlirOperationGetResult(dim, 0); 150 MlirValue constOneValue = mlirOperationGetResult(constOne, 0); 151 MlirValue loopOperands[] = {constZeroValue, dimValue, constOneValue}; 152 MlirOperationState loopState = mlirOperationStateGet( 153 mlirStringRefCreateFromCString("scf.for"), location); 154 mlirOperationStateAddOperands(&loopState, 3, loopOperands); 155 mlirOperationStateAddOwnedRegions(&loopState, 1, &loopBodyRegion); 156 MlirOperation loop = mlirOperationCreate(&loopState); 157 mlirBlockAppendOwnedOperation(funcBody, loop); 158 159 populateLoopBody(ctx, loopBody, location, funcBody); 160 161 MlirOperationState retState = mlirOperationStateGet( 162 mlirStringRefCreateFromCString("std.return"), location); 163 MlirOperation ret = mlirOperationCreate(&retState); 164 mlirBlockAppendOwnedOperation(funcBody, ret); 165 166 MlirOperation module = mlirModuleGetOperation(moduleOp); 167 mlirOperationDump(module); 168 // clang-format off 169 // CHECK: module { 170 // CHECK: func @add(%[[ARG0:.*]]: memref<?xf32>, %[[ARG1:.*]]: memref<?xf32>) { 171 // CHECK: %[[C0:.*]] = arith.constant 0 : index 172 // CHECK: %[[DIM:.*]] = memref.dim %[[ARG0]], %[[C0]] : memref<?xf32> 173 // CHECK: %[[C1:.*]] = arith.constant 1 : index 174 // CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[DIM]] step %[[C1]] { 175 // CHECK: %[[LHS:.*]] = memref.load %[[ARG0]][%[[I]]] : memref<?xf32> 176 // CHECK: %[[RHS:.*]] = memref.load %[[ARG1]][%[[I]]] : memref<?xf32> 177 // CHECK: %[[SUM:.*]] = arith.addf %[[LHS]], %[[RHS]] : f32 178 // CHECK: memref.store %[[SUM]], %[[ARG0]][%[[I]]] : memref<?xf32> 179 // CHECK: } 180 // CHECK: return 181 // CHECK: } 182 // CHECK: } 183 // clang-format on 184 185 return moduleOp; 186 } 187 188 struct OpListNode { 189 MlirOperation op; 190 struct OpListNode *next; 191 }; 192 typedef struct OpListNode OpListNode; 193 194 struct ModuleStats { 195 unsigned numOperations; 196 unsigned numAttributes; 197 unsigned numBlocks; 198 unsigned numRegions; 199 unsigned numValues; 200 unsigned numBlockArguments; 201 unsigned numOpResults; 202 }; 203 typedef struct ModuleStats ModuleStats; 204 205 int collectStatsSingle(OpListNode *head, ModuleStats *stats) { 206 MlirOperation operation = head->op; 207 stats->numOperations += 1; 208 stats->numValues += mlirOperationGetNumResults(operation); 209 stats->numAttributes += mlirOperationGetNumAttributes(operation); 210 211 unsigned numRegions = mlirOperationGetNumRegions(operation); 212 213 stats->numRegions += numRegions; 214 215 intptr_t numResults = mlirOperationGetNumResults(operation); 216 for (intptr_t i = 0; i < numResults; ++i) { 217 MlirValue result = mlirOperationGetResult(operation, i); 218 if (!mlirValueIsAOpResult(result)) 219 return 1; 220 if (mlirValueIsABlockArgument(result)) 221 return 2; 222 if (!mlirOperationEqual(operation, mlirOpResultGetOwner(result))) 223 return 3; 224 if (i != mlirOpResultGetResultNumber(result)) 225 return 4; 226 ++stats->numOpResults; 227 } 228 229 MlirRegion region = mlirOperationGetFirstRegion(operation); 230 while (!mlirRegionIsNull(region)) { 231 for (MlirBlock block = mlirRegionGetFirstBlock(region); 232 !mlirBlockIsNull(block); block = mlirBlockGetNextInRegion(block)) { 233 ++stats->numBlocks; 234 intptr_t numArgs = mlirBlockGetNumArguments(block); 235 stats->numValues += numArgs; 236 for (intptr_t j = 0; j < numArgs; ++j) { 237 MlirValue arg = mlirBlockGetArgument(block, j); 238 if (!mlirValueIsABlockArgument(arg)) 239 return 5; 240 if (mlirValueIsAOpResult(arg)) 241 return 6; 242 if (!mlirBlockEqual(block, mlirBlockArgumentGetOwner(arg))) 243 return 7; 244 if (j != mlirBlockArgumentGetArgNumber(arg)) 245 return 8; 246 ++stats->numBlockArguments; 247 } 248 249 for (MlirOperation child = mlirBlockGetFirstOperation(block); 250 !mlirOperationIsNull(child); 251 child = mlirOperationGetNextInBlock(child)) { 252 OpListNode *node = malloc(sizeof(OpListNode)); 253 node->op = child; 254 node->next = head->next; 255 head->next = node; 256 } 257 } 258 region = mlirRegionGetNextInOperation(region); 259 } 260 return 0; 261 } 262 263 int collectStats(MlirOperation operation) { 264 OpListNode *head = malloc(sizeof(OpListNode)); 265 head->op = operation; 266 head->next = NULL; 267 268 ModuleStats stats; 269 stats.numOperations = 0; 270 stats.numAttributes = 0; 271 stats.numBlocks = 0; 272 stats.numRegions = 0; 273 stats.numValues = 0; 274 stats.numBlockArguments = 0; 275 stats.numOpResults = 0; 276 277 do { 278 int retval = collectStatsSingle(head, &stats); 279 if (retval) { 280 free(head); 281 return retval; 282 } 283 OpListNode *next = head->next; 284 free(head); 285 head = next; 286 } while (head); 287 288 if (stats.numValues != stats.numBlockArguments + stats.numOpResults) 289 return 100; 290 291 fprintf(stderr, "@stats\n"); 292 fprintf(stderr, "Number of operations: %u\n", stats.numOperations); 293 fprintf(stderr, "Number of attributes: %u\n", stats.numAttributes); 294 fprintf(stderr, "Number of blocks: %u\n", stats.numBlocks); 295 fprintf(stderr, "Number of regions: %u\n", stats.numRegions); 296 fprintf(stderr, "Number of values: %u\n", stats.numValues); 297 fprintf(stderr, "Number of block arguments: %u\n", stats.numBlockArguments); 298 fprintf(stderr, "Number of op results: %u\n", stats.numOpResults); 299 // clang-format off 300 // CHECK-LABEL: @stats 301 // CHECK: Number of operations: 12 302 // CHECK: Number of attributes: 4 303 // CHECK: Number of blocks: 3 304 // CHECK: Number of regions: 3 305 // CHECK: Number of values: 9 306 // CHECK: Number of block arguments: 3 307 // CHECK: Number of op results: 6 308 // clang-format on 309 return 0; 310 } 311 312 static void printToStderr(MlirStringRef str, void *userData) { 313 (void)userData; 314 fwrite(str.data, 1, str.length, stderr); 315 } 316 317 static void printFirstOfEach(MlirContext ctx, MlirOperation operation) { 318 // Assuming we are given a module, go to the first operation of the first 319 // function. 320 MlirRegion region = mlirOperationGetRegion(operation, 0); 321 MlirBlock block = mlirRegionGetFirstBlock(region); 322 operation = mlirBlockGetFirstOperation(block); 323 region = mlirOperationGetRegion(operation, 0); 324 MlirOperation parentOperation = operation; 325 block = mlirRegionGetFirstBlock(region); 326 operation = mlirBlockGetFirstOperation(block); 327 assert(mlirModuleIsNull(mlirModuleFromOperation(operation))); 328 329 // Verify that parent operation and block report correctly. 330 // CHECK: Parent operation eq: 1 331 fprintf(stderr, "Parent operation eq: %d\n", 332 mlirOperationEqual(mlirOperationGetParentOperation(operation), 333 parentOperation)); 334 // CHECK: Block eq: 1 335 fprintf(stderr, "Block eq: %d\n", 336 mlirBlockEqual(mlirOperationGetBlock(operation), block)); 337 // CHECK: Block parent operation eq: 1 338 fprintf( 339 stderr, "Block parent operation eq: %d\n", 340 mlirOperationEqual(mlirBlockGetParentOperation(block), parentOperation)); 341 // CHECK: Block parent region eq: 1 342 fprintf(stderr, "Block parent region eq: %d\n", 343 mlirRegionEqual(mlirBlockGetParentRegion(block), region)); 344 345 // In the module we created, the first operation of the first function is 346 // an "memref.dim", which has an attribute and a single result that we can 347 // use to test the printing mechanism. 348 mlirBlockPrint(block, printToStderr, NULL); 349 fprintf(stderr, "\n"); 350 fprintf(stderr, "First operation: "); 351 mlirOperationPrint(operation, printToStderr, NULL); 352 fprintf(stderr, "\n"); 353 // clang-format off 354 // CHECK: %[[C0:.*]] = arith.constant 0 : index 355 // CHECK: %[[DIM:.*]] = memref.dim %{{.*}}, %[[C0]] : memref<?xf32> 356 // CHECK: %[[C1:.*]] = arith.constant 1 : index 357 // CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[DIM]] step %[[C1]] { 358 // CHECK: %[[LHS:.*]] = memref.load %{{.*}}[%[[I]]] : memref<?xf32> 359 // CHECK: %[[RHS:.*]] = memref.load %{{.*}}[%[[I]]] : memref<?xf32> 360 // CHECK: %[[SUM:.*]] = arith.addf %[[LHS]], %[[RHS]] : f32 361 // CHECK: memref.store %[[SUM]], %{{.*}}[%[[I]]] : memref<?xf32> 362 // CHECK: } 363 // CHECK: return 364 // CHECK: First operation: {{.*}} = arith.constant 0 : index 365 // clang-format on 366 367 // Get the operation name and print it. 368 MlirIdentifier ident = mlirOperationGetName(operation); 369 MlirStringRef identStr = mlirIdentifierStr(ident); 370 fprintf(stderr, "Operation name: '"); 371 for (size_t i = 0; i < identStr.length; ++i) 372 fputc(identStr.data[i], stderr); 373 fprintf(stderr, "'\n"); 374 // CHECK: Operation name: 'arith.constant' 375 376 // Get the identifier again and verify equal. 377 MlirIdentifier identAgain = mlirIdentifierGet(ctx, identStr); 378 fprintf(stderr, "Identifier equal: %d\n", 379 mlirIdentifierEqual(ident, identAgain)); 380 // CHECK: Identifier equal: 1 381 382 // Get the block terminator and print it. 383 MlirOperation terminator = mlirBlockGetTerminator(block); 384 fprintf(stderr, "Terminator: "); 385 mlirOperationPrint(terminator, printToStderr, NULL); 386 fprintf(stderr, "\n"); 387 // CHECK: Terminator: return 388 389 // Get the attribute by index. 390 MlirNamedAttribute namedAttr0 = mlirOperationGetAttribute(operation, 0); 391 fprintf(stderr, "Get attr 0: "); 392 mlirAttributePrint(namedAttr0.attribute, printToStderr, NULL); 393 fprintf(stderr, "\n"); 394 // CHECK: Get attr 0: 0 : index 395 396 // Now re-get the attribute by name. 397 MlirAttribute attr0ByName = mlirOperationGetAttributeByName( 398 operation, mlirIdentifierStr(namedAttr0.name)); 399 fprintf(stderr, "Get attr 0 by name: "); 400 mlirAttributePrint(attr0ByName, printToStderr, NULL); 401 fprintf(stderr, "\n"); 402 // CHECK: Get attr 0 by name: 0 : index 403 404 // Get a non-existing attribute and assert that it is null (sanity). 405 fprintf(stderr, "does_not_exist is null: %d\n", 406 mlirAttributeIsNull(mlirOperationGetAttributeByName( 407 operation, mlirStringRefCreateFromCString("does_not_exist")))); 408 // CHECK: does_not_exist is null: 1 409 410 // Get result 0 and its type. 411 MlirValue value = mlirOperationGetResult(operation, 0); 412 fprintf(stderr, "Result 0: "); 413 mlirValuePrint(value, printToStderr, NULL); 414 fprintf(stderr, "\n"); 415 fprintf(stderr, "Value is null: %d\n", mlirValueIsNull(value)); 416 // CHECK: Result 0: {{.*}} = arith.constant 0 : index 417 // CHECK: Value is null: 0 418 419 MlirType type = mlirValueGetType(value); 420 fprintf(stderr, "Result 0 type: "); 421 mlirTypePrint(type, printToStderr, NULL); 422 fprintf(stderr, "\n"); 423 // CHECK: Result 0 type: index 424 425 // Set a custom attribute. 426 mlirOperationSetAttributeByName(operation, 427 mlirStringRefCreateFromCString("custom_attr"), 428 mlirBoolAttrGet(ctx, 1)); 429 fprintf(stderr, "Op with set attr: "); 430 mlirOperationPrint(operation, printToStderr, NULL); 431 fprintf(stderr, "\n"); 432 // CHECK: Op with set attr: {{.*}} {custom_attr = true} 433 434 // Remove the attribute. 435 fprintf(stderr, "Remove attr: %d\n", 436 mlirOperationRemoveAttributeByName( 437 operation, mlirStringRefCreateFromCString("custom_attr"))); 438 fprintf(stderr, "Remove attr again: %d\n", 439 mlirOperationRemoveAttributeByName( 440 operation, mlirStringRefCreateFromCString("custom_attr"))); 441 fprintf(stderr, "Removed attr is null: %d\n", 442 mlirAttributeIsNull(mlirOperationGetAttributeByName( 443 operation, mlirStringRefCreateFromCString("custom_attr")))); 444 // CHECK: Remove attr: 1 445 // CHECK: Remove attr again: 0 446 // CHECK: Removed attr is null: 1 447 448 // Add a large attribute to verify printing flags. 449 int64_t eltsShape[] = {4}; 450 int32_t eltsData[] = {1, 2, 3, 4}; 451 mlirOperationSetAttributeByName( 452 operation, mlirStringRefCreateFromCString("elts"), 453 mlirDenseElementsAttrInt32Get( 454 mlirRankedTensorTypeGet(1, eltsShape, mlirIntegerTypeGet(ctx, 32), 455 mlirAttributeGetNull()), 456 4, eltsData)); 457 MlirOpPrintingFlags flags = mlirOpPrintingFlagsCreate(); 458 mlirOpPrintingFlagsElideLargeElementsAttrs(flags, 2); 459 mlirOpPrintingFlagsPrintGenericOpForm(flags); 460 mlirOpPrintingFlagsEnableDebugInfo(flags, /*prettyForm=*/0); 461 mlirOpPrintingFlagsUseLocalScope(flags); 462 fprintf(stderr, "Op print with all flags: "); 463 mlirOperationPrintWithFlags(operation, flags, printToStderr, NULL); 464 fprintf(stderr, "\n"); 465 // clang-format off 466 // CHECK: Op print with all flags: %{{.*}} = "arith.constant"() {elts = opaque<"_", "0xDEADBEEF"> : tensor<4xi32>, value = 0 : index} : () -> index loc(unknown) 467 // clang-format on 468 469 mlirOpPrintingFlagsDestroy(flags); 470 } 471 472 static int constructAndTraverseIr(MlirContext ctx) { 473 MlirLocation location = mlirLocationUnknownGet(ctx); 474 475 MlirModule moduleOp = makeAndDumpAdd(ctx, location); 476 MlirOperation module = mlirModuleGetOperation(moduleOp); 477 assert(!mlirModuleIsNull(mlirModuleFromOperation(module))); 478 479 int errcode = collectStats(module); 480 if (errcode) 481 return errcode; 482 483 printFirstOfEach(ctx, module); 484 485 mlirModuleDestroy(moduleOp); 486 return 0; 487 } 488 489 /// Creates an operation with a region containing multiple blocks with 490 /// operations and dumps it. The blocks and operations are inserted using 491 /// block/operation-relative API and their final order is checked. 492 static void buildWithInsertionsAndPrint(MlirContext ctx) { 493 MlirLocation loc = mlirLocationUnknownGet(ctx); 494 mlirContextSetAllowUnregisteredDialects(ctx, true); 495 496 MlirRegion owningRegion = mlirRegionCreate(); 497 MlirBlock nullBlock = mlirRegionGetFirstBlock(owningRegion); 498 MlirOperationState state = mlirOperationStateGet( 499 mlirStringRefCreateFromCString("insertion.order.test"), loc); 500 mlirOperationStateAddOwnedRegions(&state, 1, &owningRegion); 501 MlirOperation op = mlirOperationCreate(&state); 502 MlirRegion region = mlirOperationGetRegion(op, 0); 503 504 // Use integer types of different bitwidth as block arguments in order to 505 // differentiate blocks. 506 MlirType i1 = mlirIntegerTypeGet(ctx, 1); 507 MlirType i2 = mlirIntegerTypeGet(ctx, 2); 508 MlirType i3 = mlirIntegerTypeGet(ctx, 3); 509 MlirType i4 = mlirIntegerTypeGet(ctx, 4); 510 MlirBlock block1 = mlirBlockCreate(1, &i1); 511 MlirBlock block2 = mlirBlockCreate(1, &i2); 512 MlirBlock block3 = mlirBlockCreate(1, &i3); 513 MlirBlock block4 = mlirBlockCreate(1, &i4); 514 // Insert blocks so as to obtain the 1-2-3-4 order, 515 mlirRegionInsertOwnedBlockBefore(region, nullBlock, block3); 516 mlirRegionInsertOwnedBlockBefore(region, block3, block2); 517 mlirRegionInsertOwnedBlockAfter(region, nullBlock, block1); 518 mlirRegionInsertOwnedBlockAfter(region, block3, block4); 519 520 MlirOperationState op1State = 521 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op1"), loc); 522 MlirOperationState op2State = 523 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op2"), loc); 524 MlirOperationState op3State = 525 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op3"), loc); 526 MlirOperationState op4State = 527 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op4"), loc); 528 MlirOperationState op5State = 529 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op5"), loc); 530 MlirOperationState op6State = 531 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op6"), loc); 532 MlirOperationState op7State = 533 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op7"), loc); 534 MlirOperation op1 = mlirOperationCreate(&op1State); 535 MlirOperation op2 = mlirOperationCreate(&op2State); 536 MlirOperation op3 = mlirOperationCreate(&op3State); 537 MlirOperation op4 = mlirOperationCreate(&op4State); 538 MlirOperation op5 = mlirOperationCreate(&op5State); 539 MlirOperation op6 = mlirOperationCreate(&op6State); 540 MlirOperation op7 = mlirOperationCreate(&op7State); 541 542 // Insert operations in the first block so as to obtain the 1-2-3-4 order. 543 MlirOperation nullOperation = mlirBlockGetFirstOperation(block1); 544 assert(mlirOperationIsNull(nullOperation)); 545 mlirBlockInsertOwnedOperationBefore(block1, nullOperation, op3); 546 mlirBlockInsertOwnedOperationBefore(block1, op3, op2); 547 mlirBlockInsertOwnedOperationAfter(block1, nullOperation, op1); 548 mlirBlockInsertOwnedOperationAfter(block1, op3, op4); 549 550 // Append operations to the rest of blocks to make them non-empty and thus 551 // printable. 552 mlirBlockAppendOwnedOperation(block2, op5); 553 mlirBlockAppendOwnedOperation(block3, op6); 554 mlirBlockAppendOwnedOperation(block4, op7); 555 556 mlirOperationDump(op); 557 mlirOperationDestroy(op); 558 mlirContextSetAllowUnregisteredDialects(ctx, false); 559 // clang-format off 560 // CHECK-LABEL: "insertion.order.test" 561 // CHECK: ^{{.*}}(%{{.*}}: i1 562 // CHECK: "dummy.op1" 563 // CHECK-NEXT: "dummy.op2" 564 // CHECK-NEXT: "dummy.op3" 565 // CHECK-NEXT: "dummy.op4" 566 // CHECK: ^{{.*}}(%{{.*}}: i2 567 // CHECK: "dummy.op5" 568 // CHECK: ^{{.*}}(%{{.*}}: i3 569 // CHECK: "dummy.op6" 570 // CHECK: ^{{.*}}(%{{.*}}: i4 571 // CHECK: "dummy.op7" 572 // clang-format on 573 } 574 575 /// Creates operations with type inference and tests various failure modes. 576 static int createOperationWithTypeInference(MlirContext ctx) { 577 MlirLocation loc = mlirLocationUnknownGet(ctx); 578 MlirAttribute iAttr = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 32), 4); 579 580 // The shape.const_size op implements result type inference and is only used 581 // for that reason. 582 MlirOperationState state = mlirOperationStateGet( 583 mlirStringRefCreateFromCString("shape.const_size"), loc); 584 MlirNamedAttribute valueAttr = mlirNamedAttributeGet( 585 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), iAttr); 586 mlirOperationStateAddAttributes(&state, 1, &valueAttr); 587 mlirOperationStateEnableResultTypeInference(&state); 588 589 // Expect result type inference to succeed. 590 MlirOperation op = mlirOperationCreate(&state); 591 if (mlirOperationIsNull(op)) { 592 fprintf(stderr, "ERROR: Result type inference unexpectedly failed"); 593 return 1; 594 } 595 596 // CHECK: RESULT_TYPE_INFERENCE: !shape.size 597 fprintf(stderr, "RESULT_TYPE_INFERENCE: "); 598 mlirTypeDump(mlirValueGetType(mlirOperationGetResult(op, 0))); 599 fprintf(stderr, "\n"); 600 mlirOperationDestroy(op); 601 return 0; 602 } 603 604 /// Dumps instances of all builtin types to check that C API works correctly. 605 /// Additionally, performs simple identity checks that a builtin type 606 /// constructed with C API can be inspected and has the expected type. The 607 /// latter achieves full coverage of C API for builtin types. Returns 0 on 608 /// success and a non-zero error code on failure. 609 static int printBuiltinTypes(MlirContext ctx) { 610 // Integer types. 611 MlirType i32 = mlirIntegerTypeGet(ctx, 32); 612 MlirType si32 = mlirIntegerTypeSignedGet(ctx, 32); 613 MlirType ui32 = mlirIntegerTypeUnsignedGet(ctx, 32); 614 if (!mlirTypeIsAInteger(i32) || mlirTypeIsAF32(i32)) 615 return 1; 616 if (!mlirTypeIsAInteger(si32) || !mlirIntegerTypeIsSigned(si32)) 617 return 2; 618 if (!mlirTypeIsAInteger(ui32) || !mlirIntegerTypeIsUnsigned(ui32)) 619 return 3; 620 if (mlirTypeEqual(i32, ui32) || mlirTypeEqual(i32, si32)) 621 return 4; 622 if (mlirIntegerTypeGetWidth(i32) != mlirIntegerTypeGetWidth(si32)) 623 return 5; 624 fprintf(stderr, "@types\n"); 625 mlirTypeDump(i32); 626 fprintf(stderr, "\n"); 627 mlirTypeDump(si32); 628 fprintf(stderr, "\n"); 629 mlirTypeDump(ui32); 630 fprintf(stderr, "\n"); 631 // CHECK-LABEL: @types 632 // CHECK: i32 633 // CHECK: si32 634 // CHECK: ui32 635 636 // Index type. 637 MlirType index = mlirIndexTypeGet(ctx); 638 if (!mlirTypeIsAIndex(index)) 639 return 6; 640 mlirTypeDump(index); 641 fprintf(stderr, "\n"); 642 // CHECK: index 643 644 // Floating-point types. 645 MlirType bf16 = mlirBF16TypeGet(ctx); 646 MlirType f16 = mlirF16TypeGet(ctx); 647 MlirType f32 = mlirF32TypeGet(ctx); 648 MlirType f64 = mlirF64TypeGet(ctx); 649 if (!mlirTypeIsABF16(bf16)) 650 return 7; 651 if (!mlirTypeIsAF16(f16)) 652 return 9; 653 if (!mlirTypeIsAF32(f32)) 654 return 10; 655 if (!mlirTypeIsAF64(f64)) 656 return 11; 657 mlirTypeDump(bf16); 658 fprintf(stderr, "\n"); 659 mlirTypeDump(f16); 660 fprintf(stderr, "\n"); 661 mlirTypeDump(f32); 662 fprintf(stderr, "\n"); 663 mlirTypeDump(f64); 664 fprintf(stderr, "\n"); 665 // CHECK: bf16 666 // CHECK: f16 667 // CHECK: f32 668 // CHECK: f64 669 670 // None type. 671 MlirType none = mlirNoneTypeGet(ctx); 672 if (!mlirTypeIsANone(none)) 673 return 12; 674 mlirTypeDump(none); 675 fprintf(stderr, "\n"); 676 // CHECK: none 677 678 // Complex type. 679 MlirType cplx = mlirComplexTypeGet(f32); 680 if (!mlirTypeIsAComplex(cplx) || 681 !mlirTypeEqual(mlirComplexTypeGetElementType(cplx), f32)) 682 return 13; 683 mlirTypeDump(cplx); 684 fprintf(stderr, "\n"); 685 // CHECK: complex<f32> 686 687 // Vector (and Shaped) type. ShapedType is a common base class for vectors, 688 // memrefs and tensors, one cannot create instances of this class so it is 689 // tested on an instance of vector type. 690 int64_t shape[] = {2, 3}; 691 MlirType vector = 692 mlirVectorTypeGet(sizeof(shape) / sizeof(int64_t), shape, f32); 693 if (!mlirTypeIsAVector(vector) || !mlirTypeIsAShaped(vector)) 694 return 14; 695 if (!mlirTypeEqual(mlirShapedTypeGetElementType(vector), f32) || 696 !mlirShapedTypeHasRank(vector) || mlirShapedTypeGetRank(vector) != 2 || 697 mlirShapedTypeGetDimSize(vector, 0) != 2 || 698 mlirShapedTypeIsDynamicDim(vector, 0) || 699 mlirShapedTypeGetDimSize(vector, 1) != 3 || 700 !mlirShapedTypeHasStaticShape(vector)) 701 return 15; 702 mlirTypeDump(vector); 703 fprintf(stderr, "\n"); 704 // CHECK: vector<2x3xf32> 705 706 // Ranked tensor type. 707 MlirType rankedTensor = mlirRankedTensorTypeGet( 708 sizeof(shape) / sizeof(int64_t), shape, f32, mlirAttributeGetNull()); 709 if (!mlirTypeIsATensor(rankedTensor) || 710 !mlirTypeIsARankedTensor(rankedTensor) || 711 !mlirAttributeIsNull(mlirRankedTensorTypeGetEncoding(rankedTensor))) 712 return 16; 713 mlirTypeDump(rankedTensor); 714 fprintf(stderr, "\n"); 715 // CHECK: tensor<2x3xf32> 716 717 // Unranked tensor type. 718 MlirType unrankedTensor = mlirUnrankedTensorTypeGet(f32); 719 if (!mlirTypeIsATensor(unrankedTensor) || 720 !mlirTypeIsAUnrankedTensor(unrankedTensor) || 721 mlirShapedTypeHasRank(unrankedTensor)) 722 return 17; 723 mlirTypeDump(unrankedTensor); 724 fprintf(stderr, "\n"); 725 // CHECK: tensor<*xf32> 726 727 // MemRef type. 728 MlirAttribute memSpace2 = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 64), 2); 729 MlirType memRef = mlirMemRefTypeContiguousGet( 730 f32, sizeof(shape) / sizeof(int64_t), shape, memSpace2); 731 if (!mlirTypeIsAMemRef(memRef) || 732 !mlirAttributeEqual(mlirMemRefTypeGetMemorySpace(memRef), memSpace2)) 733 return 18; 734 mlirTypeDump(memRef); 735 fprintf(stderr, "\n"); 736 // CHECK: memref<2x3xf32, 2> 737 738 // Unranked MemRef type. 739 MlirAttribute memSpace4 = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 64), 4); 740 MlirType unrankedMemRef = mlirUnrankedMemRefTypeGet(f32, memSpace4); 741 if (!mlirTypeIsAUnrankedMemRef(unrankedMemRef) || 742 mlirTypeIsAMemRef(unrankedMemRef) || 743 !mlirAttributeEqual(mlirUnrankedMemrefGetMemorySpace(unrankedMemRef), 744 memSpace4)) 745 return 19; 746 mlirTypeDump(unrankedMemRef); 747 fprintf(stderr, "\n"); 748 // CHECK: memref<*xf32, 4> 749 750 // Tuple type. 751 MlirType types[] = {unrankedMemRef, f32}; 752 MlirType tuple = mlirTupleTypeGet(ctx, 2, types); 753 if (!mlirTypeIsATuple(tuple) || mlirTupleTypeGetNumTypes(tuple) != 2 || 754 !mlirTypeEqual(mlirTupleTypeGetType(tuple, 0), unrankedMemRef) || 755 !mlirTypeEqual(mlirTupleTypeGetType(tuple, 1), f32)) 756 return 20; 757 mlirTypeDump(tuple); 758 fprintf(stderr, "\n"); 759 // CHECK: tuple<memref<*xf32, 4>, f32> 760 761 // Function type. 762 MlirType funcInputs[2] = {mlirIndexTypeGet(ctx), mlirIntegerTypeGet(ctx, 1)}; 763 MlirType funcResults[3] = {mlirIntegerTypeGet(ctx, 16), 764 mlirIntegerTypeGet(ctx, 32), 765 mlirIntegerTypeGet(ctx, 64)}; 766 MlirType funcType = mlirFunctionTypeGet(ctx, 2, funcInputs, 3, funcResults); 767 if (mlirFunctionTypeGetNumInputs(funcType) != 2) 768 return 21; 769 if (mlirFunctionTypeGetNumResults(funcType) != 3) 770 return 22; 771 if (!mlirTypeEqual(funcInputs[0], mlirFunctionTypeGetInput(funcType, 0)) || 772 !mlirTypeEqual(funcInputs[1], mlirFunctionTypeGetInput(funcType, 1))) 773 return 23; 774 if (!mlirTypeEqual(funcResults[0], mlirFunctionTypeGetResult(funcType, 0)) || 775 !mlirTypeEqual(funcResults[1], mlirFunctionTypeGetResult(funcType, 1)) || 776 !mlirTypeEqual(funcResults[2], mlirFunctionTypeGetResult(funcType, 2))) 777 return 24; 778 mlirTypeDump(funcType); 779 fprintf(stderr, "\n"); 780 // CHECK: (index, i1) -> (i16, i32, i64) 781 782 return 0; 783 } 784 785 void callbackSetFixedLengthString(const char *data, intptr_t len, 786 void *userData) { 787 strncpy(userData, data, len); 788 } 789 790 bool stringIsEqual(const char *lhs, MlirStringRef rhs) { 791 if (strlen(lhs) != rhs.length) { 792 return false; 793 } 794 return !strncmp(lhs, rhs.data, rhs.length); 795 } 796 797 int printBuiltinAttributes(MlirContext ctx) { 798 MlirAttribute floating = 799 mlirFloatAttrDoubleGet(ctx, mlirF64TypeGet(ctx), 2.0); 800 if (!mlirAttributeIsAFloat(floating) || 801 fabs(mlirFloatAttrGetValueDouble(floating) - 2.0) > 1E-6) 802 return 1; 803 fprintf(stderr, "@attrs\n"); 804 mlirAttributeDump(floating); 805 // CHECK-LABEL: @attrs 806 // CHECK: 2.000000e+00 : f64 807 808 // Exercise mlirAttributeGetType() just for the first one. 809 MlirType floatingType = mlirAttributeGetType(floating); 810 mlirTypeDump(floatingType); 811 // CHECK: f64 812 813 MlirAttribute integer = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 32), 42); 814 if (!mlirAttributeIsAInteger(integer) || 815 mlirIntegerAttrGetValueInt(integer) != 42) 816 return 2; 817 mlirAttributeDump(integer); 818 // CHECK: 42 : i32 819 820 MlirAttribute boolean = mlirBoolAttrGet(ctx, 1); 821 if (!mlirAttributeIsABool(boolean) || !mlirBoolAttrGetValue(boolean)) 822 return 3; 823 mlirAttributeDump(boolean); 824 // CHECK: true 825 826 const char data[] = "abcdefghijklmnopqestuvwxyz"; 827 MlirAttribute opaque = 828 mlirOpaqueAttrGet(ctx, mlirStringRefCreateFromCString("std"), 3, data, 829 mlirNoneTypeGet(ctx)); 830 if (!mlirAttributeIsAOpaque(opaque) || 831 !stringIsEqual("std", mlirOpaqueAttrGetDialectNamespace(opaque))) 832 return 4; 833 834 MlirStringRef opaqueData = mlirOpaqueAttrGetData(opaque); 835 if (opaqueData.length != 3 || 836 strncmp(data, opaqueData.data, opaqueData.length)) 837 return 5; 838 mlirAttributeDump(opaque); 839 // CHECK: #std.abc 840 841 MlirAttribute string = 842 mlirStringAttrGet(ctx, mlirStringRefCreate(data + 3, 2)); 843 if (!mlirAttributeIsAString(string)) 844 return 6; 845 846 MlirStringRef stringValue = mlirStringAttrGetValue(string); 847 if (stringValue.length != 2 || 848 strncmp(data + 3, stringValue.data, stringValue.length)) 849 return 7; 850 mlirAttributeDump(string); 851 // CHECK: "de" 852 853 MlirAttribute flatSymbolRef = 854 mlirFlatSymbolRefAttrGet(ctx, mlirStringRefCreate(data + 5, 3)); 855 if (!mlirAttributeIsAFlatSymbolRef(flatSymbolRef)) 856 return 8; 857 858 MlirStringRef flatSymbolRefValue = 859 mlirFlatSymbolRefAttrGetValue(flatSymbolRef); 860 if (flatSymbolRefValue.length != 3 || 861 strncmp(data + 5, flatSymbolRefValue.data, flatSymbolRefValue.length)) 862 return 9; 863 mlirAttributeDump(flatSymbolRef); 864 // CHECK: @fgh 865 866 MlirAttribute symbols[] = {flatSymbolRef, flatSymbolRef}; 867 MlirAttribute symbolRef = 868 mlirSymbolRefAttrGet(ctx, mlirStringRefCreate(data + 8, 2), 2, symbols); 869 if (!mlirAttributeIsASymbolRef(symbolRef) || 870 mlirSymbolRefAttrGetNumNestedReferences(symbolRef) != 2 || 871 !mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef, 0), 872 flatSymbolRef) || 873 !mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef, 1), 874 flatSymbolRef)) 875 return 10; 876 877 MlirStringRef symbolRefLeaf = mlirSymbolRefAttrGetLeafReference(symbolRef); 878 MlirStringRef symbolRefRoot = mlirSymbolRefAttrGetRootReference(symbolRef); 879 if (symbolRefLeaf.length != 3 || 880 strncmp(data + 5, symbolRefLeaf.data, symbolRefLeaf.length) || 881 symbolRefRoot.length != 2 || 882 strncmp(data + 8, symbolRefRoot.data, symbolRefRoot.length)) 883 return 11; 884 mlirAttributeDump(symbolRef); 885 // CHECK: @ij::@fgh::@fgh 886 887 MlirAttribute type = mlirTypeAttrGet(mlirF32TypeGet(ctx)); 888 if (!mlirAttributeIsAType(type) || 889 !mlirTypeEqual(mlirF32TypeGet(ctx), mlirTypeAttrGetValue(type))) 890 return 12; 891 mlirAttributeDump(type); 892 // CHECK: f32 893 894 MlirAttribute unit = mlirUnitAttrGet(ctx); 895 if (!mlirAttributeIsAUnit(unit)) 896 return 13; 897 mlirAttributeDump(unit); 898 // CHECK: unit 899 900 int64_t shape[] = {1, 2}; 901 902 int bools[] = {0, 1}; 903 uint8_t uints8[] = {0u, 1u}; 904 int8_t ints8[] = {0, 1}; 905 uint32_t uints32[] = {0u, 1u}; 906 int32_t ints32[] = {0, 1}; 907 uint64_t uints64[] = {0u, 1u}; 908 int64_t ints64[] = {0, 1}; 909 float floats[] = {0.0f, 1.0f}; 910 double doubles[] = {0.0, 1.0}; 911 MlirAttribute encoding = mlirAttributeGetNull(); 912 MlirAttribute boolElements = mlirDenseElementsAttrBoolGet( 913 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 1), encoding), 914 2, bools); 915 MlirAttribute uint8Elements = mlirDenseElementsAttrUInt8Get( 916 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 8), 917 encoding), 918 2, uints8); 919 MlirAttribute int8Elements = mlirDenseElementsAttrInt8Get( 920 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 8), encoding), 921 2, ints8); 922 MlirAttribute uint32Elements = mlirDenseElementsAttrUInt32Get( 923 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 32), 924 encoding), 925 2, uints32); 926 MlirAttribute int32Elements = mlirDenseElementsAttrInt32Get( 927 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32), encoding), 928 2, ints32); 929 MlirAttribute uint64Elements = mlirDenseElementsAttrUInt64Get( 930 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 64), 931 encoding), 932 2, uints64); 933 MlirAttribute int64Elements = mlirDenseElementsAttrInt64Get( 934 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding), 935 2, ints64); 936 MlirAttribute floatElements = mlirDenseElementsAttrFloatGet( 937 mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 2, 938 floats); 939 MlirAttribute doubleElements = mlirDenseElementsAttrDoubleGet( 940 mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx), encoding), 2, 941 doubles); 942 943 if (!mlirAttributeIsADenseElements(boolElements) || 944 !mlirAttributeIsADenseElements(uint8Elements) || 945 !mlirAttributeIsADenseElements(int8Elements) || 946 !mlirAttributeIsADenseElements(uint32Elements) || 947 !mlirAttributeIsADenseElements(int32Elements) || 948 !mlirAttributeIsADenseElements(uint64Elements) || 949 !mlirAttributeIsADenseElements(int64Elements) || 950 !mlirAttributeIsADenseElements(floatElements) || 951 !mlirAttributeIsADenseElements(doubleElements)) 952 return 14; 953 954 if (mlirDenseElementsAttrGetBoolValue(boolElements, 1) != 1 || 955 mlirDenseElementsAttrGetUInt8Value(uint8Elements, 1) != 1 || 956 mlirDenseElementsAttrGetInt8Value(int8Elements, 1) != 1 || 957 mlirDenseElementsAttrGetUInt32Value(uint32Elements, 1) != 1 || 958 mlirDenseElementsAttrGetInt32Value(int32Elements, 1) != 1 || 959 mlirDenseElementsAttrGetUInt64Value(uint64Elements, 1) != 1 || 960 mlirDenseElementsAttrGetInt64Value(int64Elements, 1) != 1 || 961 fabsf(mlirDenseElementsAttrGetFloatValue(floatElements, 1) - 1.0f) > 962 1E-6f || 963 fabs(mlirDenseElementsAttrGetDoubleValue(doubleElements, 1) - 1.0) > 1E-6) 964 return 15; 965 966 mlirAttributeDump(boolElements); 967 mlirAttributeDump(uint8Elements); 968 mlirAttributeDump(int8Elements); 969 mlirAttributeDump(uint32Elements); 970 mlirAttributeDump(int32Elements); 971 mlirAttributeDump(uint64Elements); 972 mlirAttributeDump(int64Elements); 973 mlirAttributeDump(floatElements); 974 mlirAttributeDump(doubleElements); 975 // CHECK: dense<{{\[}}[false, true]]> : tensor<1x2xi1> 976 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui8> 977 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi8> 978 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui32> 979 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi32> 980 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui64> 981 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi64> 982 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf32> 983 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf64> 984 985 MlirAttribute splatBool = mlirDenseElementsAttrBoolSplatGet( 986 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 1), encoding), 987 1); 988 MlirAttribute splatUInt8 = mlirDenseElementsAttrUInt8SplatGet( 989 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 8), 990 encoding), 991 1); 992 MlirAttribute splatInt8 = mlirDenseElementsAttrInt8SplatGet( 993 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 8), encoding), 994 1); 995 MlirAttribute splatUInt32 = mlirDenseElementsAttrUInt32SplatGet( 996 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 32), 997 encoding), 998 1); 999 MlirAttribute splatInt32 = mlirDenseElementsAttrInt32SplatGet( 1000 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32), encoding), 1001 1); 1002 MlirAttribute splatUInt64 = mlirDenseElementsAttrUInt64SplatGet( 1003 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 64), 1004 encoding), 1005 1); 1006 MlirAttribute splatInt64 = mlirDenseElementsAttrInt64SplatGet( 1007 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding), 1008 1); 1009 MlirAttribute splatFloat = mlirDenseElementsAttrFloatSplatGet( 1010 mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 1.0f); 1011 MlirAttribute splatDouble = mlirDenseElementsAttrDoubleSplatGet( 1012 mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx), encoding), 1.0); 1013 1014 if (!mlirAttributeIsADenseElements(splatBool) || 1015 !mlirDenseElementsAttrIsSplat(splatBool) || 1016 !mlirAttributeIsADenseElements(splatUInt8) || 1017 !mlirDenseElementsAttrIsSplat(splatUInt8) || 1018 !mlirAttributeIsADenseElements(splatInt8) || 1019 !mlirDenseElementsAttrIsSplat(splatInt8) || 1020 !mlirAttributeIsADenseElements(splatUInt32) || 1021 !mlirDenseElementsAttrIsSplat(splatUInt32) || 1022 !mlirAttributeIsADenseElements(splatInt32) || 1023 !mlirDenseElementsAttrIsSplat(splatInt32) || 1024 !mlirAttributeIsADenseElements(splatUInt64) || 1025 !mlirDenseElementsAttrIsSplat(splatUInt64) || 1026 !mlirAttributeIsADenseElements(splatInt64) || 1027 !mlirDenseElementsAttrIsSplat(splatInt64) || 1028 !mlirAttributeIsADenseElements(splatFloat) || 1029 !mlirDenseElementsAttrIsSplat(splatFloat) || 1030 !mlirAttributeIsADenseElements(splatDouble) || 1031 !mlirDenseElementsAttrIsSplat(splatDouble)) 1032 return 16; 1033 1034 if (mlirDenseElementsAttrGetBoolSplatValue(splatBool) != 1 || 1035 mlirDenseElementsAttrGetUInt8SplatValue(splatUInt8) != 1 || 1036 mlirDenseElementsAttrGetInt8SplatValue(splatInt8) != 1 || 1037 mlirDenseElementsAttrGetUInt32SplatValue(splatUInt32) != 1 || 1038 mlirDenseElementsAttrGetInt32SplatValue(splatInt32) != 1 || 1039 mlirDenseElementsAttrGetUInt64SplatValue(splatUInt64) != 1 || 1040 mlirDenseElementsAttrGetInt64SplatValue(splatInt64) != 1 || 1041 fabsf(mlirDenseElementsAttrGetFloatSplatValue(splatFloat) - 1.0f) > 1042 1E-6f || 1043 fabs(mlirDenseElementsAttrGetDoubleSplatValue(splatDouble) - 1.0) > 1E-6) 1044 return 17; 1045 1046 uint8_t *uint8RawData = 1047 (uint8_t *)mlirDenseElementsAttrGetRawData(uint8Elements); 1048 int8_t *int8RawData = (int8_t *)mlirDenseElementsAttrGetRawData(int8Elements); 1049 uint32_t *uint32RawData = 1050 (uint32_t *)mlirDenseElementsAttrGetRawData(uint32Elements); 1051 int32_t *int32RawData = 1052 (int32_t *)mlirDenseElementsAttrGetRawData(int32Elements); 1053 uint64_t *uint64RawData = 1054 (uint64_t *)mlirDenseElementsAttrGetRawData(uint64Elements); 1055 int64_t *int64RawData = 1056 (int64_t *)mlirDenseElementsAttrGetRawData(int64Elements); 1057 float *floatRawData = (float *)mlirDenseElementsAttrGetRawData(floatElements); 1058 double *doubleRawData = 1059 (double *)mlirDenseElementsAttrGetRawData(doubleElements); 1060 if (uint8RawData[0] != 0u || uint8RawData[1] != 1u || int8RawData[0] != 0 || 1061 int8RawData[1] != 1 || uint32RawData[0] != 0u || uint32RawData[1] != 1u || 1062 int32RawData[0] != 0 || int32RawData[1] != 1 || uint64RawData[0] != 0u || 1063 uint64RawData[1] != 1u || int64RawData[0] != 0 || int64RawData[1] != 1 || 1064 floatRawData[0] != 0.0f || floatRawData[1] != 1.0f || 1065 doubleRawData[0] != 0.0 || doubleRawData[1] != 1.0) 1066 return 18; 1067 1068 mlirAttributeDump(splatBool); 1069 mlirAttributeDump(splatUInt8); 1070 mlirAttributeDump(splatInt8); 1071 mlirAttributeDump(splatUInt32); 1072 mlirAttributeDump(splatInt32); 1073 mlirAttributeDump(splatUInt64); 1074 mlirAttributeDump(splatInt64); 1075 mlirAttributeDump(splatFloat); 1076 mlirAttributeDump(splatDouble); 1077 // CHECK: dense<true> : tensor<1x2xi1> 1078 // CHECK: dense<1> : tensor<1x2xui8> 1079 // CHECK: dense<1> : tensor<1x2xi8> 1080 // CHECK: dense<1> : tensor<1x2xui32> 1081 // CHECK: dense<1> : tensor<1x2xi32> 1082 // CHECK: dense<1> : tensor<1x2xui64> 1083 // CHECK: dense<1> : tensor<1x2xi64> 1084 // CHECK: dense<1.000000e+00> : tensor<1x2xf32> 1085 // CHECK: dense<1.000000e+00> : tensor<1x2xf64> 1086 1087 mlirAttributeDump(mlirElementsAttrGetValue(floatElements, 2, uints64)); 1088 mlirAttributeDump(mlirElementsAttrGetValue(doubleElements, 2, uints64)); 1089 // CHECK: 1.000000e+00 : f32 1090 // CHECK: 1.000000e+00 : f64 1091 1092 int64_t indices[] = {0, 1}; 1093 int64_t one = 1; 1094 MlirAttribute indicesAttr = mlirDenseElementsAttrInt64Get( 1095 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding), 1096 2, indices); 1097 MlirAttribute valuesAttr = mlirDenseElementsAttrFloatGet( 1098 mlirRankedTensorTypeGet(1, &one, mlirF32TypeGet(ctx), encoding), 1, 1099 floats); 1100 MlirAttribute sparseAttr = mlirSparseElementsAttribute( 1101 mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 1102 indicesAttr, valuesAttr); 1103 mlirAttributeDump(sparseAttr); 1104 // CHECK: sparse<{{\[}}[0, 1]], 0.000000e+00> : tensor<1x2xf32> 1105 1106 return 0; 1107 } 1108 1109 int printAffineMap(MlirContext ctx) { 1110 MlirAffineMap emptyAffineMap = mlirAffineMapEmptyGet(ctx); 1111 MlirAffineMap affineMap = mlirAffineMapZeroResultGet(ctx, 3, 2); 1112 MlirAffineMap constAffineMap = mlirAffineMapConstantGet(ctx, 2); 1113 MlirAffineMap multiDimIdentityAffineMap = 1114 mlirAffineMapMultiDimIdentityGet(ctx, 3); 1115 MlirAffineMap minorIdentityAffineMap = 1116 mlirAffineMapMinorIdentityGet(ctx, 3, 2); 1117 unsigned permutation[] = {1, 2, 0}; 1118 MlirAffineMap permutationAffineMap = mlirAffineMapPermutationGet( 1119 ctx, sizeof(permutation) / sizeof(unsigned), permutation); 1120 1121 fprintf(stderr, "@affineMap\n"); 1122 mlirAffineMapDump(emptyAffineMap); 1123 mlirAffineMapDump(affineMap); 1124 mlirAffineMapDump(constAffineMap); 1125 mlirAffineMapDump(multiDimIdentityAffineMap); 1126 mlirAffineMapDump(minorIdentityAffineMap); 1127 mlirAffineMapDump(permutationAffineMap); 1128 // CHECK-LABEL: @affineMap 1129 // CHECK: () -> () 1130 // CHECK: (d0, d1, d2)[s0, s1] -> () 1131 // CHECK: () -> (2) 1132 // CHECK: (d0, d1, d2) -> (d0, d1, d2) 1133 // CHECK: (d0, d1, d2) -> (d1, d2) 1134 // CHECK: (d0, d1, d2) -> (d1, d2, d0) 1135 1136 if (!mlirAffineMapIsIdentity(emptyAffineMap) || 1137 mlirAffineMapIsIdentity(affineMap) || 1138 mlirAffineMapIsIdentity(constAffineMap) || 1139 !mlirAffineMapIsIdentity(multiDimIdentityAffineMap) || 1140 mlirAffineMapIsIdentity(minorIdentityAffineMap) || 1141 mlirAffineMapIsIdentity(permutationAffineMap)) 1142 return 1; 1143 1144 if (!mlirAffineMapIsMinorIdentity(emptyAffineMap) || 1145 mlirAffineMapIsMinorIdentity(affineMap) || 1146 !mlirAffineMapIsMinorIdentity(multiDimIdentityAffineMap) || 1147 !mlirAffineMapIsMinorIdentity(minorIdentityAffineMap) || 1148 mlirAffineMapIsMinorIdentity(permutationAffineMap)) 1149 return 2; 1150 1151 if (!mlirAffineMapIsEmpty(emptyAffineMap) || 1152 mlirAffineMapIsEmpty(affineMap) || mlirAffineMapIsEmpty(constAffineMap) || 1153 mlirAffineMapIsEmpty(multiDimIdentityAffineMap) || 1154 mlirAffineMapIsEmpty(minorIdentityAffineMap) || 1155 mlirAffineMapIsEmpty(permutationAffineMap)) 1156 return 3; 1157 1158 if (mlirAffineMapIsSingleConstant(emptyAffineMap) || 1159 mlirAffineMapIsSingleConstant(affineMap) || 1160 !mlirAffineMapIsSingleConstant(constAffineMap) || 1161 mlirAffineMapIsSingleConstant(multiDimIdentityAffineMap) || 1162 mlirAffineMapIsSingleConstant(minorIdentityAffineMap) || 1163 mlirAffineMapIsSingleConstant(permutationAffineMap)) 1164 return 4; 1165 1166 if (mlirAffineMapGetSingleConstantResult(constAffineMap) != 2) 1167 return 5; 1168 1169 if (mlirAffineMapGetNumDims(emptyAffineMap) != 0 || 1170 mlirAffineMapGetNumDims(affineMap) != 3 || 1171 mlirAffineMapGetNumDims(constAffineMap) != 0 || 1172 mlirAffineMapGetNumDims(multiDimIdentityAffineMap) != 3 || 1173 mlirAffineMapGetNumDims(minorIdentityAffineMap) != 3 || 1174 mlirAffineMapGetNumDims(permutationAffineMap) != 3) 1175 return 6; 1176 1177 if (mlirAffineMapGetNumSymbols(emptyAffineMap) != 0 || 1178 mlirAffineMapGetNumSymbols(affineMap) != 2 || 1179 mlirAffineMapGetNumSymbols(constAffineMap) != 0 || 1180 mlirAffineMapGetNumSymbols(multiDimIdentityAffineMap) != 0 || 1181 mlirAffineMapGetNumSymbols(minorIdentityAffineMap) != 0 || 1182 mlirAffineMapGetNumSymbols(permutationAffineMap) != 0) 1183 return 7; 1184 1185 if (mlirAffineMapGetNumResults(emptyAffineMap) != 0 || 1186 mlirAffineMapGetNumResults(affineMap) != 0 || 1187 mlirAffineMapGetNumResults(constAffineMap) != 1 || 1188 mlirAffineMapGetNumResults(multiDimIdentityAffineMap) != 3 || 1189 mlirAffineMapGetNumResults(minorIdentityAffineMap) != 2 || 1190 mlirAffineMapGetNumResults(permutationAffineMap) != 3) 1191 return 8; 1192 1193 if (mlirAffineMapGetNumInputs(emptyAffineMap) != 0 || 1194 mlirAffineMapGetNumInputs(affineMap) != 5 || 1195 mlirAffineMapGetNumInputs(constAffineMap) != 0 || 1196 mlirAffineMapGetNumInputs(multiDimIdentityAffineMap) != 3 || 1197 mlirAffineMapGetNumInputs(minorIdentityAffineMap) != 3 || 1198 mlirAffineMapGetNumInputs(permutationAffineMap) != 3) 1199 return 9; 1200 1201 if (!mlirAffineMapIsProjectedPermutation(emptyAffineMap) || 1202 !mlirAffineMapIsPermutation(emptyAffineMap) || 1203 mlirAffineMapIsProjectedPermutation(affineMap) || 1204 mlirAffineMapIsPermutation(affineMap) || 1205 mlirAffineMapIsProjectedPermutation(constAffineMap) || 1206 mlirAffineMapIsPermutation(constAffineMap) || 1207 !mlirAffineMapIsProjectedPermutation(multiDimIdentityAffineMap) || 1208 !mlirAffineMapIsPermutation(multiDimIdentityAffineMap) || 1209 !mlirAffineMapIsProjectedPermutation(minorIdentityAffineMap) || 1210 mlirAffineMapIsPermutation(minorIdentityAffineMap) || 1211 !mlirAffineMapIsProjectedPermutation(permutationAffineMap) || 1212 !mlirAffineMapIsPermutation(permutationAffineMap)) 1213 return 10; 1214 1215 intptr_t sub[] = {1}; 1216 1217 MlirAffineMap subMap = mlirAffineMapGetSubMap( 1218 multiDimIdentityAffineMap, sizeof(sub) / sizeof(intptr_t), sub); 1219 MlirAffineMap majorSubMap = 1220 mlirAffineMapGetMajorSubMap(multiDimIdentityAffineMap, 1); 1221 MlirAffineMap minorSubMap = 1222 mlirAffineMapGetMinorSubMap(multiDimIdentityAffineMap, 1); 1223 1224 mlirAffineMapDump(subMap); 1225 mlirAffineMapDump(majorSubMap); 1226 mlirAffineMapDump(minorSubMap); 1227 // CHECK: (d0, d1, d2) -> (d1) 1228 // CHECK: (d0, d1, d2) -> (d0) 1229 // CHECK: (d0, d1, d2) -> (d2) 1230 1231 return 0; 1232 } 1233 1234 int printAffineExpr(MlirContext ctx) { 1235 MlirAffineExpr affineDimExpr = mlirAffineDimExprGet(ctx, 5); 1236 MlirAffineExpr affineSymbolExpr = mlirAffineSymbolExprGet(ctx, 5); 1237 MlirAffineExpr affineConstantExpr = mlirAffineConstantExprGet(ctx, 5); 1238 MlirAffineExpr affineAddExpr = 1239 mlirAffineAddExprGet(affineDimExpr, affineSymbolExpr); 1240 MlirAffineExpr affineMulExpr = 1241 mlirAffineMulExprGet(affineDimExpr, affineSymbolExpr); 1242 MlirAffineExpr affineModExpr = 1243 mlirAffineModExprGet(affineDimExpr, affineSymbolExpr); 1244 MlirAffineExpr affineFloorDivExpr = 1245 mlirAffineFloorDivExprGet(affineDimExpr, affineSymbolExpr); 1246 MlirAffineExpr affineCeilDivExpr = 1247 mlirAffineCeilDivExprGet(affineDimExpr, affineSymbolExpr); 1248 1249 // Tests mlirAffineExprDump. 1250 fprintf(stderr, "@affineExpr\n"); 1251 mlirAffineExprDump(affineDimExpr); 1252 mlirAffineExprDump(affineSymbolExpr); 1253 mlirAffineExprDump(affineConstantExpr); 1254 mlirAffineExprDump(affineAddExpr); 1255 mlirAffineExprDump(affineMulExpr); 1256 mlirAffineExprDump(affineModExpr); 1257 mlirAffineExprDump(affineFloorDivExpr); 1258 mlirAffineExprDump(affineCeilDivExpr); 1259 // CHECK-LABEL: @affineExpr 1260 // CHECK: d5 1261 // CHECK: s5 1262 // CHECK: 5 1263 // CHECK: d5 + s5 1264 // CHECK: d5 * s5 1265 // CHECK: d5 mod s5 1266 // CHECK: d5 floordiv s5 1267 // CHECK: d5 ceildiv s5 1268 1269 // Tests methods of affine binary operation expression, takes add expression 1270 // as an example. 1271 mlirAffineExprDump(mlirAffineBinaryOpExprGetLHS(affineAddExpr)); 1272 mlirAffineExprDump(mlirAffineBinaryOpExprGetRHS(affineAddExpr)); 1273 // CHECK: d5 1274 // CHECK: s5 1275 1276 // Tests methods of affine dimension expression. 1277 if (mlirAffineDimExprGetPosition(affineDimExpr) != 5) 1278 return 1; 1279 1280 // Tests methods of affine symbol expression. 1281 if (mlirAffineSymbolExprGetPosition(affineSymbolExpr) != 5) 1282 return 2; 1283 1284 // Tests methods of affine constant expression. 1285 if (mlirAffineConstantExprGetValue(affineConstantExpr) != 5) 1286 return 3; 1287 1288 // Tests methods of affine expression. 1289 if (mlirAffineExprIsSymbolicOrConstant(affineDimExpr) || 1290 !mlirAffineExprIsSymbolicOrConstant(affineSymbolExpr) || 1291 !mlirAffineExprIsSymbolicOrConstant(affineConstantExpr) || 1292 mlirAffineExprIsSymbolicOrConstant(affineAddExpr) || 1293 mlirAffineExprIsSymbolicOrConstant(affineMulExpr) || 1294 mlirAffineExprIsSymbolicOrConstant(affineModExpr) || 1295 mlirAffineExprIsSymbolicOrConstant(affineFloorDivExpr) || 1296 mlirAffineExprIsSymbolicOrConstant(affineCeilDivExpr)) 1297 return 4; 1298 1299 if (!mlirAffineExprIsPureAffine(affineDimExpr) || 1300 !mlirAffineExprIsPureAffine(affineSymbolExpr) || 1301 !mlirAffineExprIsPureAffine(affineConstantExpr) || 1302 !mlirAffineExprIsPureAffine(affineAddExpr) || 1303 mlirAffineExprIsPureAffine(affineMulExpr) || 1304 mlirAffineExprIsPureAffine(affineModExpr) || 1305 mlirAffineExprIsPureAffine(affineFloorDivExpr) || 1306 mlirAffineExprIsPureAffine(affineCeilDivExpr)) 1307 return 5; 1308 1309 if (mlirAffineExprGetLargestKnownDivisor(affineDimExpr) != 1 || 1310 mlirAffineExprGetLargestKnownDivisor(affineSymbolExpr) != 1 || 1311 mlirAffineExprGetLargestKnownDivisor(affineConstantExpr) != 5 || 1312 mlirAffineExprGetLargestKnownDivisor(affineAddExpr) != 1 || 1313 mlirAffineExprGetLargestKnownDivisor(affineMulExpr) != 1 || 1314 mlirAffineExprGetLargestKnownDivisor(affineModExpr) != 1 || 1315 mlirAffineExprGetLargestKnownDivisor(affineFloorDivExpr) != 1 || 1316 mlirAffineExprGetLargestKnownDivisor(affineCeilDivExpr) != 1) 1317 return 6; 1318 1319 if (!mlirAffineExprIsMultipleOf(affineDimExpr, 1) || 1320 !mlirAffineExprIsMultipleOf(affineSymbolExpr, 1) || 1321 !mlirAffineExprIsMultipleOf(affineConstantExpr, 5) || 1322 !mlirAffineExprIsMultipleOf(affineAddExpr, 1) || 1323 !mlirAffineExprIsMultipleOf(affineMulExpr, 1) || 1324 !mlirAffineExprIsMultipleOf(affineModExpr, 1) || 1325 !mlirAffineExprIsMultipleOf(affineFloorDivExpr, 1) || 1326 !mlirAffineExprIsMultipleOf(affineCeilDivExpr, 1)) 1327 return 7; 1328 1329 if (!mlirAffineExprIsFunctionOfDim(affineDimExpr, 5) || 1330 mlirAffineExprIsFunctionOfDim(affineSymbolExpr, 5) || 1331 mlirAffineExprIsFunctionOfDim(affineConstantExpr, 5) || 1332 !mlirAffineExprIsFunctionOfDim(affineAddExpr, 5) || 1333 !mlirAffineExprIsFunctionOfDim(affineMulExpr, 5) || 1334 !mlirAffineExprIsFunctionOfDim(affineModExpr, 5) || 1335 !mlirAffineExprIsFunctionOfDim(affineFloorDivExpr, 5) || 1336 !mlirAffineExprIsFunctionOfDim(affineCeilDivExpr, 5)) 1337 return 8; 1338 1339 // Tests 'IsA' methods of affine binary operation expression. 1340 if (!mlirAffineExprIsAAdd(affineAddExpr)) 1341 return 9; 1342 1343 if (!mlirAffineExprIsAMul(affineMulExpr)) 1344 return 10; 1345 1346 if (!mlirAffineExprIsAMod(affineModExpr)) 1347 return 11; 1348 1349 if (!mlirAffineExprIsAFloorDiv(affineFloorDivExpr)) 1350 return 12; 1351 1352 if (!mlirAffineExprIsACeilDiv(affineCeilDivExpr)) 1353 return 13; 1354 1355 if (!mlirAffineExprIsABinary(affineAddExpr)) 1356 return 14; 1357 1358 // Test other 'IsA' method on affine expressions. 1359 if (!mlirAffineExprIsAConstant(affineConstantExpr)) 1360 return 15; 1361 1362 if (!mlirAffineExprIsADim(affineDimExpr)) 1363 return 16; 1364 1365 if (!mlirAffineExprIsASymbol(affineSymbolExpr)) 1366 return 17; 1367 1368 // Test equality and nullity. 1369 MlirAffineExpr otherDimExpr = mlirAffineDimExprGet(ctx, 5); 1370 if (!mlirAffineExprEqual(affineDimExpr, otherDimExpr)) 1371 return 18; 1372 1373 if (mlirAffineExprIsNull(affineDimExpr)) 1374 return 19; 1375 1376 return 0; 1377 } 1378 1379 int affineMapFromExprs(MlirContext ctx) { 1380 MlirAffineExpr affineDimExpr = mlirAffineDimExprGet(ctx, 0); 1381 MlirAffineExpr affineSymbolExpr = mlirAffineSymbolExprGet(ctx, 1); 1382 MlirAffineExpr exprs[] = {affineDimExpr, affineSymbolExpr}; 1383 MlirAffineMap map = mlirAffineMapGet(ctx, 3, 3, 2, exprs); 1384 1385 // CHECK-LABEL: @affineMapFromExprs 1386 fprintf(stderr, "@affineMapFromExprs"); 1387 // CHECK: (d0, d1, d2)[s0, s1, s2] -> (d0, s1) 1388 mlirAffineMapDump(map); 1389 1390 if (mlirAffineMapGetNumResults(map) != 2) 1391 return 1; 1392 1393 if (!mlirAffineExprEqual(mlirAffineMapGetResult(map, 0), affineDimExpr)) 1394 return 2; 1395 1396 if (!mlirAffineExprEqual(mlirAffineMapGetResult(map, 1), affineSymbolExpr)) 1397 return 3; 1398 1399 MlirAffineExpr affineDim2Expr = mlirAffineDimExprGet(ctx, 1); 1400 MlirAffineExpr composed = mlirAffineExprCompose(affineDim2Expr, map); 1401 // CHECK: s1 1402 mlirAffineExprDump(composed); 1403 if (!mlirAffineExprEqual(composed, affineSymbolExpr)) 1404 return 4; 1405 1406 return 0; 1407 } 1408 1409 int printIntegerSet(MlirContext ctx) { 1410 MlirIntegerSet emptySet = mlirIntegerSetEmptyGet(ctx, 2, 1); 1411 1412 // CHECK-LABEL: @printIntegerSet 1413 fprintf(stderr, "@printIntegerSet"); 1414 1415 // CHECK: (d0, d1)[s0] : (1 == 0) 1416 mlirIntegerSetDump(emptySet); 1417 1418 if (!mlirIntegerSetIsCanonicalEmpty(emptySet)) 1419 return 1; 1420 1421 MlirIntegerSet anotherEmptySet = mlirIntegerSetEmptyGet(ctx, 2, 1); 1422 if (!mlirIntegerSetEqual(emptySet, anotherEmptySet)) 1423 return 2; 1424 1425 // Construct a set constrained by: 1426 // d0 - s0 == 0, 1427 // d1 - 42 >= 0. 1428 MlirAffineExpr negOne = mlirAffineConstantExprGet(ctx, -1); 1429 MlirAffineExpr negFortyTwo = mlirAffineConstantExprGet(ctx, -42); 1430 MlirAffineExpr d0 = mlirAffineDimExprGet(ctx, 0); 1431 MlirAffineExpr d1 = mlirAffineDimExprGet(ctx, 1); 1432 MlirAffineExpr s0 = mlirAffineSymbolExprGet(ctx, 0); 1433 MlirAffineExpr negS0 = mlirAffineMulExprGet(negOne, s0); 1434 MlirAffineExpr d0minusS0 = mlirAffineAddExprGet(d0, negS0); 1435 MlirAffineExpr d1minus42 = mlirAffineAddExprGet(d1, negFortyTwo); 1436 MlirAffineExpr constraints[] = {d0minusS0, d1minus42}; 1437 bool flags[] = {true, false}; 1438 1439 MlirIntegerSet set = mlirIntegerSetGet(ctx, 2, 1, 2, constraints, flags); 1440 // CHECK: (d0, d1)[s0] : ( 1441 // CHECK-DAG: d0 - s0 == 0 1442 // CHECK-DAG: d1 - 42 >= 0 1443 mlirIntegerSetDump(set); 1444 1445 // Transform d1 into s0. 1446 MlirAffineExpr s1 = mlirAffineSymbolExprGet(ctx, 1); 1447 MlirAffineExpr repl[] = {d0, s1}; 1448 MlirIntegerSet replaced = mlirIntegerSetReplaceGet(set, repl, &s0, 1, 2); 1449 // CHECK: (d0)[s0, s1] : ( 1450 // CHECK-DAG: d0 - s0 == 0 1451 // CHECK-DAG: s1 - 42 >= 0 1452 mlirIntegerSetDump(replaced); 1453 1454 if (mlirIntegerSetGetNumDims(set) != 2) 1455 return 3; 1456 if (mlirIntegerSetGetNumDims(replaced) != 1) 1457 return 4; 1458 1459 if (mlirIntegerSetGetNumSymbols(set) != 1) 1460 return 5; 1461 if (mlirIntegerSetGetNumSymbols(replaced) != 2) 1462 return 6; 1463 1464 if (mlirIntegerSetGetNumInputs(set) != 3) 1465 return 7; 1466 1467 if (mlirIntegerSetGetNumConstraints(set) != 2) 1468 return 8; 1469 1470 if (mlirIntegerSetGetNumEqualities(set) != 1) 1471 return 9; 1472 1473 if (mlirIntegerSetGetNumInequalities(set) != 1) 1474 return 10; 1475 1476 MlirAffineExpr cstr1 = mlirIntegerSetGetConstraint(set, 0); 1477 MlirAffineExpr cstr2 = mlirIntegerSetGetConstraint(set, 1); 1478 bool isEq1 = mlirIntegerSetIsConstraintEq(set, 0); 1479 bool isEq2 = mlirIntegerSetIsConstraintEq(set, 1); 1480 if (!mlirAffineExprEqual(cstr1, isEq1 ? d0minusS0 : d1minus42)) 1481 return 11; 1482 if (!mlirAffineExprEqual(cstr2, isEq2 ? d0minusS0 : d1minus42)) 1483 return 12; 1484 1485 return 0; 1486 } 1487 1488 int registerOnlyStd() { 1489 MlirContext ctx = mlirContextCreate(); 1490 // The built-in dialect is always loaded. 1491 if (mlirContextGetNumLoadedDialects(ctx) != 1) 1492 return 1; 1493 1494 MlirDialectHandle stdHandle = mlirGetDialectHandle__std__(); 1495 1496 MlirDialect std = mlirContextGetOrLoadDialect( 1497 ctx, mlirDialectHandleGetNamespace(stdHandle)); 1498 if (!mlirDialectIsNull(std)) 1499 return 2; 1500 1501 mlirDialectHandleRegisterDialect(stdHandle, ctx); 1502 1503 std = mlirContextGetOrLoadDialect(ctx, 1504 mlirDialectHandleGetNamespace(stdHandle)); 1505 if (mlirDialectIsNull(std)) 1506 return 3; 1507 1508 MlirDialect alsoStd = mlirDialectHandleLoadDialect(stdHandle, ctx); 1509 if (!mlirDialectEqual(std, alsoStd)) 1510 return 4; 1511 1512 MlirStringRef stdNs = mlirDialectGetNamespace(std); 1513 MlirStringRef alsoStdNs = mlirDialectHandleGetNamespace(stdHandle); 1514 if (stdNs.length != alsoStdNs.length || 1515 strncmp(stdNs.data, alsoStdNs.data, stdNs.length)) 1516 return 5; 1517 1518 fprintf(stderr, "@registration\n"); 1519 // CHECK-LABEL: @registration 1520 1521 // CHECK: std.cond_br is_registered: 1 1522 fprintf(stderr, "std.cond_br is_registered: %d\n", 1523 mlirContextIsRegisteredOperation( 1524 ctx, mlirStringRefCreateFromCString("std.cond_br"))); 1525 1526 // CHECK: std.not_existing_op is_registered: 0 1527 fprintf(stderr, "std.not_existing_op is_registered: %d\n", 1528 mlirContextIsRegisteredOperation( 1529 ctx, mlirStringRefCreateFromCString("std.not_existing_op"))); 1530 1531 // CHECK: not_existing_dialect.not_existing_op is_registered: 0 1532 fprintf(stderr, "not_existing_dialect.not_existing_op is_registered: %d\n", 1533 mlirContextIsRegisteredOperation( 1534 ctx, mlirStringRefCreateFromCString( 1535 "not_existing_dialect.not_existing_op"))); 1536 1537 mlirContextDestroy(ctx); 1538 return 0; 1539 } 1540 1541 /// Tests backreference APIs 1542 static int testBackreferences() { 1543 fprintf(stderr, "@test_backreferences\n"); 1544 1545 MlirContext ctx = mlirContextCreate(); 1546 mlirContextSetAllowUnregisteredDialects(ctx, true); 1547 MlirLocation loc = mlirLocationUnknownGet(ctx); 1548 1549 MlirOperationState opState = 1550 mlirOperationStateGet(mlirStringRefCreateFromCString("invalid.op"), loc); 1551 MlirRegion region = mlirRegionCreate(); 1552 MlirBlock block = mlirBlockCreate(0, NULL); 1553 mlirRegionAppendOwnedBlock(region, block); 1554 mlirOperationStateAddOwnedRegions(&opState, 1, ®ion); 1555 MlirOperation op = mlirOperationCreate(&opState); 1556 MlirIdentifier ident = 1557 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("identifier")); 1558 1559 if (!mlirContextEqual(ctx, mlirOperationGetContext(op))) { 1560 fprintf(stderr, "ERROR: Getting context from operation failed\n"); 1561 return 1; 1562 } 1563 if (!mlirOperationEqual(op, mlirBlockGetParentOperation(block))) { 1564 fprintf(stderr, "ERROR: Getting parent operation from block failed\n"); 1565 return 2; 1566 } 1567 if (!mlirContextEqual(ctx, mlirIdentifierGetContext(ident))) { 1568 fprintf(stderr, "ERROR: Getting context from identifier failed\n"); 1569 return 3; 1570 } 1571 1572 mlirOperationDestroy(op); 1573 mlirContextDestroy(ctx); 1574 1575 // CHECK-LABEL: @test_backreferences 1576 return 0; 1577 } 1578 1579 /// Tests operand APIs. 1580 int testOperands() { 1581 fprintf(stderr, "@testOperands\n"); 1582 // CHECK-LABEL: @testOperands 1583 1584 MlirContext ctx = mlirContextCreate(); 1585 mlirRegisterAllDialects(ctx); 1586 mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("test")); 1587 MlirLocation loc = mlirLocationUnknownGet(ctx); 1588 MlirType indexType = mlirIndexTypeGet(ctx); 1589 1590 // Create some constants to use as operands. 1591 MlirAttribute indexZeroLiteral = 1592 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 1593 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 1594 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 1595 indexZeroLiteral); 1596 MlirOperationState constZeroState = mlirOperationStateGet( 1597 mlirStringRefCreateFromCString("arith.constant"), loc); 1598 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 1599 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 1600 MlirOperation constZero = mlirOperationCreate(&constZeroState); 1601 MlirValue constZeroValue = mlirOperationGetResult(constZero, 0); 1602 1603 MlirAttribute indexOneLiteral = 1604 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index")); 1605 MlirNamedAttribute indexOneValueAttr = mlirNamedAttributeGet( 1606 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 1607 indexOneLiteral); 1608 MlirOperationState constOneState = mlirOperationStateGet( 1609 mlirStringRefCreateFromCString("arith.constant"), loc); 1610 mlirOperationStateAddResults(&constOneState, 1, &indexType); 1611 mlirOperationStateAddAttributes(&constOneState, 1, &indexOneValueAttr); 1612 MlirOperation constOne = mlirOperationCreate(&constOneState); 1613 MlirValue constOneValue = mlirOperationGetResult(constOne, 0); 1614 1615 // Create the operation under test. 1616 mlirContextSetAllowUnregisteredDialects(ctx, true); 1617 MlirOperationState opState = 1618 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op"), loc); 1619 MlirValue initialOperands[] = {constZeroValue}; 1620 mlirOperationStateAddOperands(&opState, 1, initialOperands); 1621 MlirOperation op = mlirOperationCreate(&opState); 1622 1623 // Test operand APIs. 1624 intptr_t numOperands = mlirOperationGetNumOperands(op); 1625 fprintf(stderr, "Num Operands: %" PRIdPTR "\n", numOperands); 1626 // CHECK: Num Operands: 1 1627 1628 MlirValue opOperand = mlirOperationGetOperand(op, 0); 1629 fprintf(stderr, "Original operand: "); 1630 mlirValuePrint(opOperand, printToStderr, NULL); 1631 // CHECK: Original operand: {{.+}} arith.constant 0 : index 1632 1633 mlirOperationSetOperand(op, 0, constOneValue); 1634 opOperand = mlirOperationGetOperand(op, 0); 1635 fprintf(stderr, "Updated operand: "); 1636 mlirValuePrint(opOperand, printToStderr, NULL); 1637 // CHECK: Updated operand: {{.+}} arith.constant 1 : index 1638 1639 mlirOperationDestroy(op); 1640 mlirOperationDestroy(constZero); 1641 mlirOperationDestroy(constOne); 1642 mlirContextDestroy(ctx); 1643 1644 return 0; 1645 } 1646 1647 /// Tests clone APIs. 1648 int testClone() { 1649 fprintf(stderr, "@testClone\n"); 1650 // CHECK-LABEL: @testClone 1651 1652 MlirContext ctx = mlirContextCreate(); 1653 mlirRegisterAllDialects(ctx); 1654 mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("std")); 1655 MlirLocation loc = mlirLocationUnknownGet(ctx); 1656 MlirType indexType = mlirIndexTypeGet(ctx); 1657 MlirStringRef valueStringRef = mlirStringRefCreateFromCString("value"); 1658 1659 MlirAttribute indexZeroLiteral = 1660 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 1661 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 1662 mlirIdentifierGet(ctx, valueStringRef), indexZeroLiteral); 1663 MlirOperationState constZeroState = mlirOperationStateGet( 1664 mlirStringRefCreateFromCString("arith.constant"), loc); 1665 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 1666 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 1667 MlirOperation constZero = mlirOperationCreate(&constZeroState); 1668 1669 MlirAttribute indexOneLiteral = 1670 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index")); 1671 MlirOperation constOne = mlirOperationClone(constZero); 1672 mlirOperationSetAttributeByName(constOne, valueStringRef, indexOneLiteral); 1673 1674 mlirOperationPrint(constZero, printToStderr, NULL); 1675 mlirOperationPrint(constOne, printToStderr, NULL); 1676 // CHECK: arith.constant 0 : index 1677 // CHECK: arith.constant 1 : index 1678 1679 mlirOperationDestroy(constZero); 1680 mlirOperationDestroy(constOne); 1681 mlirContextDestroy(ctx); 1682 return 0; 1683 } 1684 1685 // Wraps a diagnostic into additional text we can match against. 1686 MlirLogicalResult errorHandler(MlirDiagnostic diagnostic, void *userData) { 1687 fprintf(stderr, "processing diagnostic (userData: %" PRIdPTR ") <<\n", 1688 (intptr_t)userData); 1689 mlirDiagnosticPrint(diagnostic, printToStderr, NULL); 1690 fprintf(stderr, "\n"); 1691 MlirLocation loc = mlirDiagnosticGetLocation(diagnostic); 1692 mlirLocationPrint(loc, printToStderr, NULL); 1693 assert(mlirDiagnosticGetNumNotes(diagnostic) == 0); 1694 fprintf(stderr, "\n>> end of diagnostic (userData: %" PRIdPTR ")\n", 1695 (intptr_t)userData); 1696 return mlirLogicalResultSuccess(); 1697 } 1698 1699 // Logs when the delete user data callback is called 1700 static void deleteUserData(void *userData) { 1701 fprintf(stderr, "deleting user data (userData: %" PRIdPTR ")\n", 1702 (intptr_t)userData); 1703 } 1704 1705 int testTypeID(MlirContext ctx) { 1706 fprintf(stderr, "@testTypeID\n"); 1707 1708 // Test getting and comparing type and attribute type ids. 1709 MlirType i32 = mlirIntegerTypeGet(ctx, 32); 1710 MlirTypeID i32ID = mlirTypeGetTypeID(i32); 1711 MlirType ui32 = mlirIntegerTypeUnsignedGet(ctx, 32); 1712 MlirTypeID ui32ID = mlirTypeGetTypeID(ui32); 1713 MlirType f32 = mlirF32TypeGet(ctx); 1714 MlirTypeID f32ID = mlirTypeGetTypeID(f32); 1715 MlirAttribute i32Attr = mlirIntegerAttrGet(i32, 1); 1716 MlirTypeID i32AttrID = mlirAttributeGetTypeID(i32Attr); 1717 1718 if (mlirTypeIDIsNull(i32ID) || mlirTypeIDIsNull(ui32ID) || 1719 mlirTypeIDIsNull(f32ID) || mlirTypeIDIsNull(i32AttrID)) { 1720 fprintf(stderr, "ERROR: Expected type ids to be present\n"); 1721 return 1; 1722 } 1723 1724 if (!mlirTypeIDEqual(i32ID, ui32ID) || 1725 mlirTypeIDHashValue(i32ID) != mlirTypeIDHashValue(ui32ID)) { 1726 fprintf( 1727 stderr, 1728 "ERROR: Expected different integer types to have the same type id\n"); 1729 return 2; 1730 } 1731 1732 if (mlirTypeIDEqual(i32ID, f32ID) || 1733 mlirTypeIDHashValue(i32ID) == mlirTypeIDHashValue(f32ID)) { 1734 fprintf(stderr, 1735 "ERROR: Expected integer type id to not equal float type id\n"); 1736 return 3; 1737 } 1738 1739 if (mlirTypeIDEqual(i32ID, i32AttrID) || 1740 mlirTypeIDHashValue(i32ID) == mlirTypeIDHashValue(i32AttrID)) { 1741 fprintf(stderr, "ERROR: Expected integer type id to not equal integer " 1742 "attribute type id\n"); 1743 return 4; 1744 } 1745 1746 MlirLocation loc = mlirLocationUnknownGet(ctx); 1747 MlirType indexType = mlirIndexTypeGet(ctx); 1748 MlirStringRef valueStringRef = mlirStringRefCreateFromCString("value"); 1749 1750 // Create a registered operation, which should have a type id. 1751 MlirAttribute indexZeroLiteral = 1752 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 1753 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 1754 mlirIdentifierGet(ctx, valueStringRef), indexZeroLiteral); 1755 MlirOperationState constZeroState = mlirOperationStateGet( 1756 mlirStringRefCreateFromCString("arith.constant"), loc); 1757 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 1758 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 1759 MlirOperation constZero = mlirOperationCreate(&constZeroState); 1760 1761 if (!mlirOperationVerify(constZero)) { 1762 fprintf(stderr, "ERROR: Expected operation to verify correctly\n"); 1763 return 5; 1764 } 1765 1766 if (mlirOperationIsNull(constZero)) { 1767 fprintf(stderr, "ERROR: Expected registered operation to be present\n"); 1768 return 6; 1769 } 1770 1771 MlirTypeID registeredOpID = mlirOperationGetTypeID(constZero); 1772 1773 if (mlirTypeIDIsNull(registeredOpID)) { 1774 fprintf(stderr, 1775 "ERROR: Expected registered operation type id to be present\n"); 1776 return 7; 1777 } 1778 1779 // Create an unregistered operation, which should not have a type id. 1780 mlirContextSetAllowUnregisteredDialects(ctx, true); 1781 MlirOperationState opState = 1782 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op"), loc); 1783 MlirOperation unregisteredOp = mlirOperationCreate(&opState); 1784 if (mlirOperationIsNull(unregisteredOp)) { 1785 fprintf(stderr, "ERROR: Expected unregistered operation to be present\n"); 1786 return 8; 1787 } 1788 1789 MlirTypeID unregisteredOpID = mlirOperationGetTypeID(unregisteredOp); 1790 1791 if (!mlirTypeIDIsNull(unregisteredOpID)) { 1792 fprintf(stderr, 1793 "ERROR: Expected unregistered operation type id to be null\n"); 1794 return 9; 1795 } 1796 1797 mlirOperationDestroy(constZero); 1798 mlirOperationDestroy(unregisteredOp); 1799 1800 return 0; 1801 } 1802 1803 int testSymbolTable(MlirContext ctx) { 1804 fprintf(stderr, "@testSymbolTable\n"); 1805 1806 const char *moduleString = "func private @foo()" 1807 "func private @bar()"; 1808 const char *otherModuleString = "func private @qux()" 1809 "func private @foo()"; 1810 1811 MlirModule module = 1812 mlirModuleCreateParse(ctx, mlirStringRefCreateFromCString(moduleString)); 1813 MlirModule otherModule = mlirModuleCreateParse( 1814 ctx, mlirStringRefCreateFromCString(otherModuleString)); 1815 1816 MlirSymbolTable symbolTable = 1817 mlirSymbolTableCreate(mlirModuleGetOperation(module)); 1818 1819 MlirOperation funcFoo = 1820 mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("foo")); 1821 if (mlirOperationIsNull(funcFoo)) 1822 return 1; 1823 1824 MlirOperation funcBar = 1825 mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("bar")); 1826 if (mlirOperationEqual(funcFoo, funcBar)) 1827 return 2; 1828 1829 MlirOperation missing = 1830 mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("qux")); 1831 if (!mlirOperationIsNull(missing)) 1832 return 3; 1833 1834 MlirBlock moduleBody = mlirModuleGetBody(module); 1835 MlirBlock otherModuleBody = mlirModuleGetBody(otherModule); 1836 MlirOperation operation = mlirBlockGetFirstOperation(otherModuleBody); 1837 mlirOperationRemoveFromParent(operation); 1838 mlirBlockAppendOwnedOperation(moduleBody, operation); 1839 1840 // At this moment, the operation is still missing from the symbol table. 1841 MlirOperation stillMissing = 1842 mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("qux")); 1843 if (!mlirOperationIsNull(stillMissing)) 1844 return 4; 1845 1846 // After it is added to the symbol table, and not only the operation with 1847 // which the table is associated, it can be looked up. 1848 mlirSymbolTableInsert(symbolTable, operation); 1849 MlirOperation funcQux = 1850 mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("qux")); 1851 if (!mlirOperationEqual(operation, funcQux)) 1852 return 5; 1853 1854 // Erasing from the symbol table also removes the operation. 1855 mlirSymbolTableErase(symbolTable, funcBar); 1856 MlirOperation nowMissing = 1857 mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("bar")); 1858 if (!mlirOperationIsNull(nowMissing)) 1859 return 6; 1860 1861 // Adding a symbol with the same name to the table should rename. 1862 MlirOperation duplicateNameOp = mlirBlockGetFirstOperation(otherModuleBody); 1863 mlirOperationRemoveFromParent(duplicateNameOp); 1864 mlirBlockAppendOwnedOperation(moduleBody, duplicateNameOp); 1865 MlirAttribute newName = mlirSymbolTableInsert(symbolTable, duplicateNameOp); 1866 MlirStringRef newNameStr = mlirStringAttrGetValue(newName); 1867 if (mlirStringRefEqual(newNameStr, mlirStringRefCreateFromCString("foo"))) 1868 return 7; 1869 MlirAttribute updatedName = mlirOperationGetAttributeByName( 1870 duplicateNameOp, mlirSymbolTableGetSymbolAttributeName()); 1871 if (!mlirAttributeEqual(updatedName, newName)) 1872 return 8; 1873 1874 mlirOperationDump(mlirModuleGetOperation(module)); 1875 mlirOperationDump(mlirModuleGetOperation(otherModule)); 1876 // clang-format off 1877 // CHECK-LABEL: @testSymbolTable 1878 // CHECK: module 1879 // CHECK: func private @foo 1880 // CHECK: func private @qux 1881 // CHECK: func private @foo{{.+}} 1882 // CHECK: module 1883 // CHECK-NOT: @qux 1884 // CHECK-NOT: @foo 1885 // clang-format on 1886 1887 mlirSymbolTableDestroy(symbolTable); 1888 mlirModuleDestroy(module); 1889 mlirModuleDestroy(otherModule); 1890 1891 return 0; 1892 } 1893 1894 void testDiagnostics() { 1895 MlirContext ctx = mlirContextCreate(); 1896 MlirDiagnosticHandlerID id = mlirContextAttachDiagnosticHandler( 1897 ctx, errorHandler, (void *)42, deleteUserData); 1898 fprintf(stderr, "@test_diagnostics\n"); 1899 MlirLocation unknownLoc = mlirLocationUnknownGet(ctx); 1900 mlirEmitError(unknownLoc, "test diagnostics"); 1901 MlirLocation fileLineColLoc = mlirLocationFileLineColGet( 1902 ctx, mlirStringRefCreateFromCString("file.c"), 1, 2); 1903 mlirEmitError(fileLineColLoc, "test diagnostics"); 1904 MlirLocation callSiteLoc = mlirLocationCallSiteGet( 1905 mlirLocationFileLineColGet( 1906 ctx, mlirStringRefCreateFromCString("other-file.c"), 2, 3), 1907 fileLineColLoc); 1908 mlirEmitError(callSiteLoc, "test diagnostics"); 1909 MlirLocation null = {0}; 1910 MlirLocation nameLoc = 1911 mlirLocationNameGet(ctx, mlirStringRefCreateFromCString("named"), null); 1912 mlirEmitError(nameLoc, "test diagnostics"); 1913 MlirLocation locs[2] = {nameLoc, callSiteLoc}; 1914 MlirAttribute nullAttr = {0}; 1915 MlirLocation fusedLoc = mlirLocationFusedGet(ctx, 2, locs, nullAttr); 1916 mlirEmitError(fusedLoc, "test diagnostics"); 1917 mlirContextDetachDiagnosticHandler(ctx, id); 1918 mlirEmitError(unknownLoc, "more test diagnostics"); 1919 // CHECK-LABEL: @test_diagnostics 1920 // CHECK: processing diagnostic (userData: 42) << 1921 // CHECK: test diagnostics 1922 // CHECK: loc(unknown) 1923 // CHECK: >> end of diagnostic (userData: 42) 1924 // CHECK: processing diagnostic (userData: 42) << 1925 // CHECK: test diagnostics 1926 // CHECK: loc("file.c":1:2) 1927 // CHECK: >> end of diagnostic (userData: 42) 1928 // CHECK: processing diagnostic (userData: 42) << 1929 // CHECK: test diagnostics 1930 // CHECK: loc(callsite("other-file.c":2:3 at "file.c":1:2)) 1931 // CHECK: >> end of diagnostic (userData: 42) 1932 // CHECK: processing diagnostic (userData: 42) << 1933 // CHECK: test diagnostics 1934 // CHECK: loc("named") 1935 // CHECK: >> end of diagnostic (userData: 42) 1936 // CHECK: processing diagnostic (userData: 42) << 1937 // CHECK: test diagnostics 1938 // CHECK: loc(fused["named", callsite("other-file.c":2:3 at "file.c":1:2)]) 1939 // CHECK: deleting user data (userData: 42) 1940 // CHECK-NOT: processing diagnostic 1941 // CHECK: more test diagnostics 1942 mlirContextDestroy(ctx); 1943 } 1944 1945 int main() { 1946 MlirContext ctx = mlirContextCreate(); 1947 mlirRegisterAllDialects(ctx); 1948 if (constructAndTraverseIr(ctx)) 1949 return 1; 1950 buildWithInsertionsAndPrint(ctx); 1951 if (createOperationWithTypeInference(ctx)) 1952 return 2; 1953 1954 if (printBuiltinTypes(ctx)) 1955 return 3; 1956 if (printBuiltinAttributes(ctx)) 1957 return 4; 1958 if (printAffineMap(ctx)) 1959 return 5; 1960 if (printAffineExpr(ctx)) 1961 return 6; 1962 if (affineMapFromExprs(ctx)) 1963 return 7; 1964 if (printIntegerSet(ctx)) 1965 return 8; 1966 if (registerOnlyStd()) 1967 return 9; 1968 if (testBackreferences()) 1969 return 10; 1970 if (testOperands()) 1971 return 11; 1972 if (testClone()) 1973 return 12; 1974 if (testTypeID(ctx)) 1975 return 13; 1976 if (testSymbolTable(ctx)) 1977 return 14; 1978 1979 mlirContextDestroy(ctx); 1980 1981 testDiagnostics(); 1982 return 0; 1983 } 1984