Skip to content

Commit

Permalink
[MLIR][LLVM] Add debug output to the LLVM inliner.
Browse files Browse the repository at this point in the history
This revealed a test case that wasn't hitting the intended branch
because the inlinees had no function definition.

Depends on D146628

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D146633
  • Loading branch information
definelicht authored and gysit committed Mar 24, 2023
1 parent 09aa3f7 commit a94d2bd
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 16 deletions.
61 changes: 51 additions & 10 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMInlining.cpp
Expand Up @@ -15,6 +15,9 @@
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/IR/Matchers.h"
#include "mlir/Transforms/InliningUtils.h"
#include "llvm/Support/Debug.h"

#define DEBUG_TYPE "llvm-inliner"

using namespace mlir;

Expand Down Expand Up @@ -134,26 +137,43 @@ struct LLVMInlinerInterface : public DialectInlinerInterface {
if (!wouldBeCloned)
return false;
auto callOp = dyn_cast<LLVM::CallOp>(call);
if (!callOp) {
LLVM_DEBUG(llvm::dbgs()
<< "Cannot inline: call is not an LLVM::CallOp\n");
return false;
}
auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(callable);
if (!callOp || !funcOp)
if (!funcOp) {
LLVM_DEBUG(llvm::dbgs()
<< "Cannot inline: callable is not an LLVM::LLVMFuncOp\n");
return false;
}
if (auto attrs = funcOp.getArgAttrs()) {
for (Attribute attr : *attrs) {
auto attrDict = cast<DictionaryAttr>(attr);
for (NamedAttribute attr : attrDict) {
if (attr.getName() == LLVM::LLVMDialect::getByValAttrName())
continue;
// TODO: Handle all argument attributes;
LLVM_DEBUG(llvm::dbgs() << "Cannot inline " << funcOp.getSymName()
<< ": unhandled argument attribute \""
<< attr.getName() << "\"\n");
return false;
}
}
}
// TODO: Handle result attributes;
if (funcOp.getResAttrs())
if (funcOp.getResAttrs()) {
LLVM_DEBUG(llvm::dbgs() << "Cannot inline " << funcOp.getSymName()
<< ": unhandled result attribute\n");
return false;
}
// TODO: Handle exceptions.
if (funcOp.getPersonality())
if (funcOp.getPersonality()) {
LLVM_DEBUG(llvm::dbgs() << "Cannot inline " << funcOp.getSymName()
<< ": unhandled function personality\n");
return false;
}
if (funcOp.getPassthrough()) {
// TODO: Used attributes should not be passthrough.
DenseSet<StringAttr> disallowed(
Expand All @@ -167,7 +187,14 @@ struct LLVMInlinerInterface : public DialectInlinerInterface {
auto stringAttr = dyn_cast<StringAttr>(attr);
if (!stringAttr)
return false;
return disallowed.contains(stringAttr);
if (disallowed.contains(stringAttr)) {
LLVM_DEBUG(llvm::dbgs()
<< "Cannot inline " << funcOp.getSymName()
<< ": found disallowed function attribute "
<< stringAttr << "\n");
return true;
}
return false;
}))
return false;
}
Expand All @@ -185,14 +212,28 @@ struct LLVMInlinerInterface : public DialectInlinerInterface {
// Some attributes on memory operations require handling during
// inlining. Since this is not yet implemented, refuse to inline memory
// operations that have any of these attributes.
if (auto iface = dyn_cast<LLVM::AliasAnalysisOpInterface>(op))
if (iface.getAliasScopesOrNull() || iface.getNoAliasScopesOrNull())
if (auto iface = dyn_cast<LLVM::AliasAnalysisOpInterface>(op)) {
if (iface.getAliasScopesOrNull() || iface.getNoAliasScopesOrNull()) {
LLVM_DEBUG(llvm::dbgs()
<< "Cannot inline: unhandled alias analysis metadata\n");
return false;
if (auto iface = dyn_cast<LLVM::AccessGroupOpInterface>(op))
if (iface.getAccessGroupsOrNull())
}
}
if (auto iface = dyn_cast<LLVM::AccessGroupOpInterface>(op)) {
if (iface.getAccessGroupsOrNull()) {
LLVM_DEBUG(llvm::dbgs()
<< "Cannot inline: unhandled access group metadata\n");
return false;
return isa<LLVM::CallOp, LLVM::AllocaOp, LLVM::LifetimeStartOp,
LLVM::LifetimeEndOp, LLVM::LoadOp, LLVM::StoreOp>(op);
}
}
if (!isa<LLVM::CallOp, LLVM::AllocaOp, LLVM::LifetimeStartOp,
LLVM::LifetimeEndOp, LLVM::LoadOp, LLVM::StoreOp>(op)) {
LLVM_DEBUG(llvm::dbgs()
<< "Cannot inline: unhandled side effecting operation \""
<< op->getName() << "\"\n");
return false;
}
return true;
}

/// Handle the given inlined return by replacing it with a branch. This
Expand Down
29 changes: 23 additions & 6 deletions mlir/test/Dialect/LLVMIR/inlining.mlir
Expand Up @@ -160,12 +160,29 @@ llvm.func @caller() {

// -----

llvm.func @callee_noinline() attributes { passthrough = ["noinline"] }
llvm.func @callee_optnone() attributes { passthrough = ["optnone"] }
llvm.func @callee_noduplicate() attributes { passthrough = ["noduplicate"] }
llvm.func @callee_presplitcoroutine() attributes { passthrough = ["presplitcoroutine"] }
llvm.func @callee_returns_twice() attributes { passthrough = ["returns_twice"] }
llvm.func @callee_strictfp() attributes { passthrough = ["strictfp"] }
llvm.func @callee_noinline() attributes { passthrough = ["noinline"] } {
llvm.return
}

llvm.func @callee_optnone() attributes { passthrough = ["optnone"] } {
llvm.return
}

llvm.func @callee_noduplicate() attributes { passthrough = ["noduplicate"] } {
llvm.return
}

llvm.func @callee_presplitcoroutine() attributes { passthrough = ["presplitcoroutine"] } {
llvm.return
}

llvm.func @callee_returns_twice() attributes { passthrough = ["returns_twice"] } {
llvm.return
}

llvm.func @callee_strictfp() attributes { passthrough = ["strictfp"] } {
llvm.return
}

// CHECK-LABEL: llvm.func @caller
// CHECK-NEXT: llvm.call @callee_noinline
Expand Down

0 comments on commit a94d2bd

Please sign in to comment.