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