1 //===- IR.cpp - C Interface for Core MLIR APIs ----------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "mlir-c/IR.h" 10 11 #include "mlir/CAPI/IR.h" 12 #include "mlir/CAPI/Utils.h" 13 #include "mlir/IR/Attributes.h" 14 #include "mlir/IR/Dialect.h" 15 #include "mlir/IR/Module.h" 16 #include "mlir/IR/Operation.h" 17 #include "mlir/IR/Types.h" 18 #include "mlir/Parser.h" 19 20 using namespace mlir; 21 22 /* ========================================================================== */ 23 /* Context API. */ 24 /* ========================================================================== */ 25 26 MlirContext mlirContextCreate() { 27 auto *context = new MLIRContext(/*loadAllDialects=*/false); 28 return wrap(context); 29 } 30 31 int mlirContextEqual(MlirContext ctx1, MlirContext ctx2) { 32 return unwrap(ctx1) == unwrap(ctx2); 33 } 34 35 void mlirContextDestroy(MlirContext context) { delete unwrap(context); } 36 37 /* ========================================================================== */ 38 /* Location API. */ 39 /* ========================================================================== */ 40 41 MlirLocation mlirLocationFileLineColGet(MlirContext context, 42 const char *filename, unsigned line, 43 unsigned col) { 44 return wrap(FileLineColLoc::get(filename, line, col, unwrap(context))); 45 } 46 47 MlirLocation mlirLocationUnknownGet(MlirContext context) { 48 return wrap(UnknownLoc::get(unwrap(context))); 49 } 50 51 void mlirLocationPrint(MlirLocation location, MlirStringCallback callback, 52 void *userData) { 53 detail::CallbackOstream stream(callback, userData); 54 unwrap(location).print(stream); 55 stream.flush(); 56 } 57 58 /* ========================================================================== */ 59 /* Module API. */ 60 /* ========================================================================== */ 61 62 MlirModule mlirModuleCreateEmpty(MlirLocation location) { 63 return wrap(ModuleOp::create(unwrap(location))); 64 } 65 66 MlirModule mlirModuleCreateParse(MlirContext context, const char *module) { 67 OwningModuleRef owning = parseSourceString(module, unwrap(context)); 68 if (!owning) 69 return MlirModule{nullptr}; 70 return MlirModule{owning.release().getOperation()}; 71 } 72 73 void mlirModuleDestroy(MlirModule module) { 74 // Transfer ownership to an OwningModuleRef so that its destructor is called. 75 OwningModuleRef(unwrap(module)); 76 } 77 78 MlirOperation mlirModuleGetOperation(MlirModule module) { 79 return wrap(unwrap(module).getOperation()); 80 } 81 82 /* ========================================================================== */ 83 /* Operation state API. */ 84 /* ========================================================================== */ 85 86 MlirOperationState mlirOperationStateGet(const char *name, MlirLocation loc) { 87 MlirOperationState state; 88 state.name = name; 89 state.location = loc; 90 state.nResults = 0; 91 state.results = nullptr; 92 state.nOperands = 0; 93 state.operands = nullptr; 94 state.nRegions = 0; 95 state.regions = nullptr; 96 state.nSuccessors = 0; 97 state.successors = nullptr; 98 state.nAttributes = 0; 99 state.attributes = nullptr; 100 return state; 101 } 102 103 #define APPEND_ELEMS(type, sizeName, elemName) \ 104 state->elemName = \ 105 (type *)realloc(state->elemName, (state->sizeName + n) * sizeof(type)); \ 106 memcpy(state->elemName + state->sizeName, elemName, n * sizeof(type)); \ 107 state->sizeName += n; 108 109 void mlirOperationStateAddResults(MlirOperationState *state, intptr_t n, 110 MlirType *results) { 111 APPEND_ELEMS(MlirType, nResults, results); 112 } 113 114 void mlirOperationStateAddOperands(MlirOperationState *state, intptr_t n, 115 MlirValue *operands) { 116 APPEND_ELEMS(MlirValue, nOperands, operands); 117 } 118 void mlirOperationStateAddOwnedRegions(MlirOperationState *state, intptr_t n, 119 MlirRegion *regions) { 120 APPEND_ELEMS(MlirRegion, nRegions, regions); 121 } 122 void mlirOperationStateAddSuccessors(MlirOperationState *state, intptr_t n, 123 MlirBlock *successors) { 124 APPEND_ELEMS(MlirBlock, nSuccessors, successors); 125 } 126 void mlirOperationStateAddAttributes(MlirOperationState *state, intptr_t n, 127 MlirNamedAttribute *attributes) { 128 APPEND_ELEMS(MlirNamedAttribute, nAttributes, attributes); 129 } 130 131 /* ========================================================================== */ 132 /* Operation API. */ 133 /* ========================================================================== */ 134 135 MlirOperation mlirOperationCreate(const MlirOperationState *state) { 136 assert(state); 137 OperationState cppState(unwrap(state->location), state->name); 138 SmallVector<Type, 4> resultStorage; 139 SmallVector<Value, 8> operandStorage; 140 SmallVector<Block *, 2> successorStorage; 141 cppState.addTypes(unwrapList(state->nResults, state->results, resultStorage)); 142 cppState.addOperands( 143 unwrapList(state->nOperands, state->operands, operandStorage)); 144 cppState.addSuccessors( 145 unwrapList(state->nSuccessors, state->successors, successorStorage)); 146 147 cppState.attributes.reserve(state->nAttributes); 148 for (intptr_t i = 0; i < state->nAttributes; ++i) 149 cppState.addAttribute(state->attributes[i].name, 150 unwrap(state->attributes[i].attribute)); 151 152 for (intptr_t i = 0; i < state->nRegions; ++i) 153 cppState.addRegion(std::unique_ptr<Region>(unwrap(state->regions[i]))); 154 155 MlirOperation result = wrap(Operation::create(cppState)); 156 free(state->results); 157 free(state->operands); 158 free(state->successors); 159 free(state->regions); 160 free(state->attributes); 161 return result; 162 } 163 164 void mlirOperationDestroy(MlirOperation op) { unwrap(op)->erase(); } 165 166 int mlirOperationIsNull(MlirOperation op) { return unwrap(op) == nullptr; } 167 168 intptr_t mlirOperationGetNumRegions(MlirOperation op) { 169 return static_cast<intptr_t>(unwrap(op)->getNumRegions()); 170 } 171 172 MlirRegion mlirOperationGetRegion(MlirOperation op, intptr_t pos) { 173 return wrap(&unwrap(op)->getRegion(static_cast<unsigned>(pos))); 174 } 175 176 MlirOperation mlirOperationGetNextInBlock(MlirOperation op) { 177 return wrap(unwrap(op)->getNextNode()); 178 } 179 180 intptr_t mlirOperationGetNumOperands(MlirOperation op) { 181 return static_cast<intptr_t>(unwrap(op)->getNumOperands()); 182 } 183 184 MlirValue mlirOperationGetOperand(MlirOperation op, intptr_t pos) { 185 return wrap(unwrap(op)->getOperand(static_cast<unsigned>(pos))); 186 } 187 188 intptr_t mlirOperationGetNumResults(MlirOperation op) { 189 return static_cast<intptr_t>(unwrap(op)->getNumResults()); 190 } 191 192 MlirValue mlirOperationGetResult(MlirOperation op, intptr_t pos) { 193 return wrap(unwrap(op)->getResult(static_cast<unsigned>(pos))); 194 } 195 196 intptr_t mlirOperationGetNumSuccessors(MlirOperation op) { 197 return static_cast<intptr_t>(unwrap(op)->getNumSuccessors()); 198 } 199 200 MlirBlock mlirOperationGetSuccessor(MlirOperation op, intptr_t pos) { 201 return wrap(unwrap(op)->getSuccessor(static_cast<unsigned>(pos))); 202 } 203 204 intptr_t mlirOperationGetNumAttributes(MlirOperation op) { 205 return static_cast<intptr_t>(unwrap(op)->getAttrs().size()); 206 } 207 208 MlirNamedAttribute mlirOperationGetAttribute(MlirOperation op, intptr_t pos) { 209 NamedAttribute attr = unwrap(op)->getAttrs()[pos]; 210 return MlirNamedAttribute{attr.first.c_str(), wrap(attr.second)}; 211 } 212 213 MlirAttribute mlirOperationGetAttributeByName(MlirOperation op, 214 const char *name) { 215 return wrap(unwrap(op)->getAttr(name)); 216 } 217 218 void mlirOperationPrint(MlirOperation op, MlirStringCallback callback, 219 void *userData) { 220 detail::CallbackOstream stream(callback, userData); 221 unwrap(op)->print(stream); 222 stream.flush(); 223 } 224 225 void mlirOperationDump(MlirOperation op) { return unwrap(op)->dump(); } 226 227 /* ========================================================================== */ 228 /* Region API. */ 229 /* ========================================================================== */ 230 231 MlirRegion mlirRegionCreate() { return wrap(new Region); } 232 233 MlirBlock mlirRegionGetFirstBlock(MlirRegion region) { 234 Region *cppRegion = unwrap(region); 235 if (cppRegion->empty()) 236 return wrap(static_cast<Block *>(nullptr)); 237 return wrap(&cppRegion->front()); 238 } 239 240 void mlirRegionAppendOwnedBlock(MlirRegion region, MlirBlock block) { 241 unwrap(region)->push_back(unwrap(block)); 242 } 243 244 void mlirRegionInsertOwnedBlock(MlirRegion region, intptr_t pos, 245 MlirBlock block) { 246 auto &blockList = unwrap(region)->getBlocks(); 247 blockList.insert(std::next(blockList.begin(), pos), unwrap(block)); 248 } 249 250 void mlirRegionDestroy(MlirRegion region) { 251 delete static_cast<Region *>(region.ptr); 252 } 253 254 int mlirRegionIsNull(MlirRegion region) { return unwrap(region) == nullptr; } 255 256 /* ========================================================================== */ 257 /* Block API. */ 258 /* ========================================================================== */ 259 260 MlirBlock mlirBlockCreate(intptr_t nArgs, MlirType *args) { 261 Block *b = new Block; 262 for (intptr_t i = 0; i < nArgs; ++i) 263 b->addArgument(unwrap(args[i])); 264 return wrap(b); 265 } 266 267 MlirBlock mlirBlockGetNextInRegion(MlirBlock block) { 268 return wrap(unwrap(block)->getNextNode()); 269 } 270 271 MlirOperation mlirBlockGetFirstOperation(MlirBlock block) { 272 Block *cppBlock = unwrap(block); 273 if (cppBlock->empty()) 274 return wrap(static_cast<Operation *>(nullptr)); 275 return wrap(&cppBlock->front()); 276 } 277 278 void mlirBlockAppendOwnedOperation(MlirBlock block, MlirOperation operation) { 279 unwrap(block)->push_back(unwrap(operation)); 280 } 281 282 void mlirBlockInsertOwnedOperation(MlirBlock block, intptr_t pos, 283 MlirOperation operation) { 284 auto &opList = unwrap(block)->getOperations(); 285 opList.insert(std::next(opList.begin(), pos), unwrap(operation)); 286 } 287 288 void mlirBlockDestroy(MlirBlock block) { delete unwrap(block); } 289 290 int mlirBlockIsNull(MlirBlock block) { return unwrap(block) == nullptr; } 291 292 intptr_t mlirBlockGetNumArguments(MlirBlock block) { 293 return static_cast<intptr_t>(unwrap(block)->getNumArguments()); 294 } 295 296 MlirValue mlirBlockGetArgument(MlirBlock block, intptr_t pos) { 297 return wrap(unwrap(block)->getArgument(static_cast<unsigned>(pos))); 298 } 299 300 void mlirBlockPrint(MlirBlock block, MlirStringCallback callback, 301 void *userData) { 302 detail::CallbackOstream stream(callback, userData); 303 unwrap(block)->print(stream); 304 stream.flush(); 305 } 306 307 /* ========================================================================== */ 308 /* Value API. */ 309 /* ========================================================================== */ 310 311 MlirType mlirValueGetType(MlirValue value) { 312 return wrap(unwrap(value).getType()); 313 } 314 315 void mlirValuePrint(MlirValue value, MlirStringCallback callback, 316 void *userData) { 317 detail::CallbackOstream stream(callback, userData); 318 unwrap(value).print(stream); 319 stream.flush(); 320 } 321 322 /* ========================================================================== */ 323 /* Type API. */ 324 /* ========================================================================== */ 325 326 MlirType mlirTypeParseGet(MlirContext context, const char *type) { 327 return wrap(mlir::parseType(type, unwrap(context))); 328 } 329 330 MlirContext mlirTypeGetContext(MlirType type) { 331 return wrap(unwrap(type).getContext()); 332 } 333 334 int mlirTypeEqual(MlirType t1, MlirType t2) { return unwrap(t1) == unwrap(t2); } 335 336 void mlirTypePrint(MlirType type, MlirStringCallback callback, void *userData) { 337 detail::CallbackOstream stream(callback, userData); 338 unwrap(type).print(stream); 339 stream.flush(); 340 } 341 342 void mlirTypeDump(MlirType type) { unwrap(type).dump(); } 343 344 /* ========================================================================== */ 345 /* Attribute API. */ 346 /* ========================================================================== */ 347 348 MlirAttribute mlirAttributeParseGet(MlirContext context, const char *attr) { 349 return wrap(mlir::parseAttribute(attr, unwrap(context))); 350 } 351 352 int mlirAttributeEqual(MlirAttribute a1, MlirAttribute a2) { 353 return unwrap(a1) == unwrap(a2); 354 } 355 356 void mlirAttributePrint(MlirAttribute attr, MlirStringCallback callback, 357 void *userData) { 358 detail::CallbackOstream stream(callback, userData); 359 unwrap(attr).print(stream); 360 stream.flush(); 361 } 362 363 void mlirAttributeDump(MlirAttribute attr) { unwrap(attr).dump(); } 364 365 MlirNamedAttribute mlirNamedAttributeGet(const char *name, MlirAttribute attr) { 366 return MlirNamedAttribute{name, attr}; 367 } 368