Creates a function based on the parsed FunctionInfo.
| 2123 | |
| 2124 | /// Creates a function based on the parsed FunctionInfo. |
| 2125 | static LogicalResult createFunction( |
| 2126 | const FunctionInfo &funcInfo, OpBuilder &builder, OpBuilder &funcBuilder, |
| 2127 | const EncodingReader &reader, LazyTypeTable &types, |
| 2128 | DebugInfoReader &debuginfo, ArrayRef<ArrayRef<uint8_t>> constants, |
| 2129 | DenseElementsAttrCache &constCache, std::vector<Value> &valueIndexList, |
| 2130 | MLIRContext &context, const BytecodeVersion &bytecodeVersion) { |
| 2131 | StringRef funcNameStr; |
| 2132 | if (failed(reader.getString(funcInfo.nameIndex, funcNameStr, context))) |
| 2133 | return reader.emitError() << "failed to get function name string at index " |
| 2134 | << funcInfo.nameIndex; |
| 2135 | if (funcNameStr.empty()) |
| 2136 | return reader.emitError() |
| 2137 | << "function name at index " << funcInfo.nameIndex << " is empty"; |
| 2138 | StringAttr funcName = builder.getStringAttr(funcNameStr); |
| 2139 | // Get the function type lazily from the type table. |
| 2140 | if (funcInfo.signatureIndex >= types.size()) |
| 2141 | return reader.emitError() |
| 2142 | << "function signature index " << funcInfo.signatureIndex |
| 2143 | << " out of bounds for function '" << funcNameStr << "'"; |
| 2144 | Type signatureType = types.getType(funcInfo.signatureIndex); |
| 2145 | if (!signatureType) |
| 2146 | return reader.emitError() |
| 2147 | << "failed to parse type at index " << funcInfo.signatureIndex |
| 2148 | << " for function '" << funcNameStr; |
| 2149 | FunctionType funcType = mlir::dyn_cast<FunctionType>(signatureType); |
| 2150 | if (!funcType) |
| 2151 | return reader.emitError() |
| 2152 | << "function signature index " << funcInfo.signatureIndex |
| 2153 | << " does not refer to a function type for function '" << funcNameStr |
| 2154 | << "', got type: " << signatureType; |
| 2155 | auto diIterator = debuginfo.getIterator(funcInfo.functionLocIndex); |
| 2156 | auto funcLoc = diIterator.next<LocationAttr>(); |
| 2157 | if (!funcLoc) |
| 2158 | return reader.emitError() |
| 2159 | << "failed to read function location for '" << funcNameStr << "'"; |
| 2160 | |
| 2161 | // Determine if it's an EntryOp based on the flag |
| 2162 | bool isEntry = |
| 2163 | (funcInfo.entryFlag & |
| 2164 | static_cast<uint8_t>(Bytecode::FunctionFlags::KindKernel)) != 0; |
| 2165 | |
| 2166 | // TODO: Handle visibility flag (Bit 0) when supported. |
| 2167 | |
| 2168 | SmallVector<Attribute, 4> argAttrs; |
| 2169 | argAttrs.reserve(funcType.getNumInputs()); |
| 2170 | for (size_t i = 0; i < funcType.getNumInputs(); ++i) |
| 2171 | argAttrs.emplace_back(builder.getDictionaryAttr({})); |
| 2172 | SmallVector<Attribute, 4> retAttrs; |
| 2173 | retAttrs.reserve(funcType.getNumResults()); |
| 2174 | ArrayAttr funcArgAttrs = builder.getArrayAttr(argAttrs); |
| 2175 | for (size_t i = 0; i < funcType.getNumResults(); ++i) |
| 2176 | retAttrs.emplace_back(builder.getDictionaryAttr({})); |
| 2177 | ArrayAttr funcRetAttrs = builder.getArrayAttr(retAttrs); |
| 2178 | |
| 2179 | // Create the appropriate operation type |
| 2180 | mlir::FunctionOpInterface funcOpIFace; |
| 2181 | if (isEntry) { |
| 2182 | // Use optimization hints from bytecode or create default empty hints |
no test coverage detected