| 2459 | } |
| 2460 | |
| 2461 | OwningOpRef<cuda_tile::ModuleOp> |
| 2462 | cuda_tile::readBytecode(llvm::MemoryBufferRef bytecodeBuffer, |
| 2463 | MLIRContext &context) { |
| 2464 | ArrayRef<uint8_t> bytecodeData( |
| 2465 | reinterpret_cast<const uint8_t *>(bytecodeBuffer.getBufferStart()), |
| 2466 | bytecodeBuffer.getBufferSize()); |
| 2467 | |
| 2468 | EncodingReader reader(bytecodeData, context); |
| 2469 | DebugInfoReader debuginfo(context, reader); |
| 2470 | |
| 2471 | BytecodeVersion bytecodeVersion; |
| 2472 | if (failed(parseHeader(reader, context, bytecodeVersion))) |
| 2473 | return reader.emitError() << "failed to parse bytecode header", nullptr; |
| 2474 | |
| 2475 | // Store section payloads to allow parsing in a specific order later. |
| 2476 | std::array<std::optional<ArrayRef<uint8_t>>, Section::NumSections + 1> |
| 2477 | sectionPayloads; |
| 2478 | |
| 2479 | // Discover all sections and store their payloads. |
| 2480 | while (true) { |
| 2481 | SectionHeader header; |
| 2482 | if (failed(parseSectionHeader(reader, header, context))) |
| 2483 | return reader.emitError() << "failed to parse section header", nullptr; |
| 2484 | |
| 2485 | // Check for the end of the bytecode stream. |
| 2486 | if (header.sectionID == Section::EndOfBytecode) { |
| 2487 | if (reader.remaining() != 0) { |
| 2488 | reader.emitError() << "end section is not the last section"; |
| 2489 | return nullptr; |
| 2490 | } |
| 2491 | break; |
| 2492 | } |
| 2493 | |
| 2494 | auto validateSectionAlignment = [&](uint64_t requiredAlignment) -> bool { |
| 2495 | if (!header.hasAlignment || (header.alignment % requiredAlignment) != 0) { |
| 2496 | reader.emitError() << "section " << static_cast<int>(header.sectionID) |
| 2497 | << " must have alignment that is a multiple of " |
| 2498 | << requiredAlignment << " bytes, but " |
| 2499 | << (header.hasAlignment |
| 2500 | ? ("has alignment of " + |
| 2501 | std::to_string(header.alignment)) |
| 2502 | : "has no alignment flag set"); |
| 2503 | return false; |
| 2504 | } |
| 2505 | return true; |
| 2506 | }; |
| 2507 | |
| 2508 | switch (header.sectionID) { |
| 2509 | case Section::String: |
| 2510 | case Section::Type: |
| 2511 | if (!validateSectionAlignment(alignof(uint32_t))) |
| 2512 | return nullptr; |
| 2513 | break; |
| 2514 | case Section::Constant: |
| 2515 | case Section::Debug: |
| 2516 | case Section::Func: |
| 2517 | if (!validateSectionAlignment(alignof(uint64_t))) |
| 2518 | return nullptr; |
nothing calls this directly
no test coverage detected