Skip to content

Commit 7f20837

Browse files
committed
cleanup convertFunctionType and related usage
1 parent bd812d0 commit 7f20837

File tree

2 files changed

+41
-33
lines changed

2 files changed

+41
-33
lines changed

mlir/include/mlir/Target/LLVMIR/ModuleImport.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -363,12 +363,10 @@ class ModuleImport {
363363
/// actual function type, which may differ from the called operand type in
364364
/// variadic functions. For indirect calls, it converts the function type
365365
/// associated with the call instruction. When the call and the callee are not
366-
/// compatible (or when nested type conversions failed), emit a warning but
367-
/// attempt translation using an indirect call (in order to represent valid
368-
/// and verified LLVM IR). The `indirectCallVal` is updated to hold the
369-
/// address for the indirect call.
366+
/// compatible (or when nested type conversions failed), emit a warning and
367+
/// update `isIncompatibleCall` to indicate it.
370368
FailureOr<LLVMFunctionType> convertFunctionType(llvm::CallBase *callInst,
371-
Value &indirectCallVal);
369+
bool &isIncompatibleCall);
372370
/// Returns the callee name, or an empty symbol if the call is not direct.
373371
FlatSymbolRefAttr convertCalleeName(llvm::CallBase *callInst);
374372
/// Converts the parameter and result attributes attached to `func` and adds

mlir/lib/Target/LLVMIR/ModuleImport.cpp

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,8 +1749,8 @@ checkFunctionTypeCompatibility(LLVMFunctionType callType,
17491749

17501750
FailureOr<LLVMFunctionType>
17511751
ModuleImport::convertFunctionType(llvm::CallBase *callInst,
1752-
Value &indirectCallVal) {
1753-
indirectCallVal = nullptr;
1752+
bool &isIncompatibleCall) {
1753+
isIncompatibleCall = false;
17541754
auto castOrFailure = [](Type convertedType) -> FailureOr<LLVMFunctionType> {
17551755
auto funcTy = dyn_cast_or_null<LLVMFunctionType>(convertedType);
17561756
if (!funcTy)
@@ -1773,14 +1773,11 @@ ModuleImport::convertFunctionType(llvm::CallBase *callInst,
17731773
if (failed(calleeType))
17741774
return failure();
17751775

1776-
// Compare the types, if they are not compatible, avoid illegal call/invoke
1777-
// operations by issuing an indirect call. Note that LLVM IR currently
1778-
// supports this usage.
1776+
// Compare the types and notify users via `isIncompatibleCall` if they are not
1777+
// compatible.
17791778
if (failed(checkFunctionTypeCompatibility(*callType, *calleeType))) {
1779+
isIncompatibleCall = true;
17801780
Location loc = translateLoc(callInst->getDebugLoc());
1781-
FlatSymbolRefAttr calleeSym = convertCalleeName(callInst);
1782-
indirectCallVal = builder.create<LLVM::AddressOfOp>(
1783-
loc, LLVM::LLVMPointerType::get(context), calleeSym);
17841781
emitWarning(loc) << "incompatible call and callee types: " << *callType
17851782
<< " and " << *calleeType;
17861783
return callType;
@@ -1900,27 +1897,34 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
19001897
/*operand_attrs=*/nullptr)
19011898
.getOperation();
19021899
}
1903-
Value indirectCallVal;
1900+
bool isIncompatibleCall;
19041901
FailureOr<LLVMFunctionType> funcTy =
1905-
convertFunctionType(callInst, indirectCallVal);
1902+
convertFunctionType(callInst, isIncompatibleCall);
19061903
if (failed(funcTy))
19071904
return failure();
19081905

19091906
FlatSymbolRefAttr callee = nullptr;
1910-
// If `indirectCallVal` is available emit an indirect call, otherwise use
1911-
// the callee name. Build an indirect call by passing an empty `callee`
1912-
// operand and insert into `operands` to include the indirect call target.
1913-
if (indirectCallVal)
1907+
if (isIncompatibleCall) {
1908+
// Use an indirect call (in order to represent valid and verifiable LLVM
1909+
// IR). Build the indirect call by passing an empty `callee` operand and
1910+
// insert into `operands` to include the indirect call target.
1911+
FlatSymbolRefAttr calleeSym = convertCalleeName(callInst);
1912+
Value indirectCallVal = builder.create<LLVM::AddressOfOp>(
1913+
translateLoc(callInst->getDebugLoc()),
1914+
LLVM::LLVMPointerType::get(context), calleeSym);
19141915
operands->insert(operands->begin(), indirectCallVal);
1915-
else
1916+
} else {
1917+
// Regular direct call using callee name.
19161918
callee = convertCalleeName(callInst);
1919+
}
19171920
CallOp callOp = builder.create<CallOp>(loc, *funcTy, callee, *operands);
19181921

19191922
if (failed(convertCallAttributes(callInst, callOp)))
19201923
return failure();
19211924

1922-
// Handle parameter and result attributes unless it's an indirect call.
1923-
if (!indirectCallVal)
1925+
// Handle parameter and result attributes unless it's an incompatible
1926+
// call.
1927+
if (!isIncompatibleCall)
19241928
convertParameterAttributes(callInst, callOp, builder);
19251929
return callOp.getOperation();
19261930
}();
@@ -1986,21 +1990,26 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
19861990
unwindArgs)))
19871991
return failure();
19881992

1989-
Value indirectCallVal;
1993+
bool isIncompatibleInvoke;
19901994
FailureOr<LLVMFunctionType> funcTy =
1991-
convertFunctionType(invokeInst, indirectCallVal);
1995+
convertFunctionType(invokeInst, isIncompatibleInvoke);
19921996
if (failed(funcTy))
19931997
return failure();
19941998

19951999
FlatSymbolRefAttr calleeName = nullptr;
1996-
// If `indirectCallVal` is available emit an indirect call, otherwise use
1997-
// the callee name. Build an indirect call by passing an empty `callee`
1998-
// operand and insert into `operands` to include the indirect call target.
1999-
if (!indirectCallVal)
2000+
if (isIncompatibleInvoke) {
2001+
// Use an indirect invoke (in order to represent valid and verifiable LLVM
2002+
// IR). Build the indirect invoke by passing an empty `callee` operand and
2003+
// insert into `operands` to include the indirect invoke target.
2004+
FlatSymbolRefAttr calleeSym = convertCalleeName(invokeInst);
2005+
Value indirectInvokeVal = builder.create<LLVM::AddressOfOp>(
2006+
translateLoc(invokeInst->getDebugLoc()),
2007+
LLVM::LLVMPointerType::get(context), calleeSym);
2008+
operands->insert(operands->begin(), indirectInvokeVal);
2009+
} else {
2010+
// Regular direct invoke using callee name.
20002011
calleeName = convertCalleeName(invokeInst);
2001-
else
2002-
operands->insert(operands->begin(), indirectCallVal);
2003-
2012+
}
20042013
// Create the invoke operation. Normal destination block arguments will be
20052014
// added later on to handle the case in which the operation result is
20062015
// included in this list.
@@ -2011,8 +2020,9 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
20112020
if (failed(convertInvokeAttributes(invokeInst, invokeOp)))
20122021
return failure();
20132022

2014-
// Handle parameter and result attributes unless it's an indirect call.
2015-
if (!indirectCallVal)
2023+
// Handle parameter and result attributes unless it's an incompatible
2024+
// invoke.
2025+
if (!isIncompatibleInvoke)
20162026
convertParameterAttributes(invokeInst, invokeOp, builder);
20172027

20182028
if (!invokeInst->getType()->isVoidTy())

0 commit comments

Comments
 (0)