diff options
Diffstat (limited to 'mlir/lib/Target/LLVMIR/ModuleImport.cpp')
-rw-r--r-- | mlir/lib/Target/LLVMIR/ModuleImport.cpp | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index bfda223..c807985 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -1031,6 +1031,16 @@ LogicalResult ModuleImport::convertAliases() { return success(); } +LogicalResult ModuleImport::convertIFuncs() { + for (llvm::GlobalIFunc &ifunc : llvmModule->ifuncs()) { + if (failed(convertIFunc(&ifunc))) { + return emitError(UnknownLoc::get(context)) + << "unhandled global ifunc: " << diag(ifunc); + } + } + return success(); +} + LogicalResult ModuleImport::convertDataLayout() { Location loc = mlirModule.getLoc(); DataLayoutImporter dataLayoutImporter(context, llvmModule->getDataLayout()); @@ -1369,6 +1379,21 @@ LogicalResult ModuleImport::convertAlias(llvm::GlobalAlias *alias) { return success(); } +LogicalResult ModuleImport::convertIFunc(llvm::GlobalIFunc *ifunc) { + OpBuilder::InsertionGuard guard = setGlobalInsertionPoint(); + + Type type = convertType(ifunc->getValueType()); + llvm::Constant *resolver = ifunc->getResolver(); + Type resolverType = convertType(resolver->getType()); + builder.create<IFuncOp>(mlirModule.getLoc(), ifunc->getName(), type, + resolver->getName(), resolverType, + convertLinkageFromLLVM(ifunc->getLinkage()), + ifunc->isDSOLocal(), ifunc->getAddressSpace(), + convertUnnamedAddrFromLLVM(ifunc->getUnnamedAddr()), + convertVisibilityFromLLVM(ifunc->getVisibility())); + return success(); +} + LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) { // Insert the global after the last one or at the start of the module. OpBuilder::InsertionGuard guard = setGlobalInsertionPoint(); @@ -1973,8 +1998,9 @@ ModuleImport::convertCallOperands(llvm::CallBase *callInst, // treated as indirect calls to constant operands that need to be converted. // Skip the callee operand if it's inline assembly, as it's handled separately // in InlineAsmOp. - if (!isa<llvm::Function>(callInst->getCalledOperand()) && !isInlineAsm) { - FailureOr<Value> called = convertValue(callInst->getCalledOperand()); + llvm::Value *calleeOperand = callInst->getCalledOperand(); + if (!isa<llvm::Function, llvm::GlobalIFunc>(calleeOperand) && !isInlineAsm) { + FailureOr<Value> called = convertValue(calleeOperand); if (failed(called)) return failure(); operands.push_back(*called); @@ -2035,12 +2061,20 @@ ModuleImport::convertFunctionType(llvm::CallBase *callInst, if (failed(callType)) return failure(); auto *callee = dyn_cast<llvm::Function>(calledOperand); + + llvm::FunctionType *origCalleeType = nullptr; + if (callee) { + origCalleeType = callee->getFunctionType(); + } else if (auto *ifunc = dyn_cast<llvm::GlobalIFunc>(calledOperand)) { + origCalleeType = cast<llvm::FunctionType>(ifunc->getValueType()); + } + // For indirect calls, return the type of the call itself. - if (!callee) + if (!origCalleeType) return callType; FailureOr<LLVMFunctionType> calleeType = - castOrFailure(convertType(callee->getFunctionType())); + castOrFailure(convertType(origCalleeType)); if (failed(calleeType)) return failure(); @@ -2059,8 +2093,8 @@ ModuleImport::convertFunctionType(llvm::CallBase *callInst, FlatSymbolRefAttr ModuleImport::convertCalleeName(llvm::CallBase *callInst) { llvm::Value *calledOperand = callInst->getCalledOperand(); - if (auto *callee = dyn_cast<llvm::Function>(calledOperand)) - return SymbolRefAttr::get(context, callee->getName()); + if (isa<llvm::Function, llvm::GlobalIFunc>(calledOperand)) + return SymbolRefAttr::get(context, calledOperand->getName()); return {}; } @@ -3162,6 +3196,8 @@ OwningOpRef<ModuleOp> mlir::translateLLVMIRToModule( return {}; if (failed(moduleImport.convertAliases())) return {}; + if (failed(moduleImport.convertIFuncs())) + return {}; moduleImport.convertTargetTriple(); return module; } |