This is an archive of the discontinued LLVM Phabricator instance.

[mlir][llvmir] Import intrinsics with attributes from LLVMIR.
ClosedPublic

Authored by gysit on Oct 6 2022, 1:02 AM.

Details

Summary

The revision adds support to specify custom import functions for
LLVM IR intrinsics with immediate arguments that translate to MLIR
attributes. It takes an approach similar to the MLIR to LLVM translation
that uses a tablegen defined build method. The default implementation
of this newly introduced "mlirBuilder" assumes all intrinsic arguments
translate to operands. Specific intrinsics, such as
llvm.lifetime.start/stop then define a custom builder that converts
their immediate arguments to MLIR attributes.

Depends on D135349

Diff Detail

Event Timeline

gysit created this revision.Oct 6 2022, 1:02 AM
Herald added a project: Restricted Project. · View Herald Transcript
gysit requested review of this revision.Oct 6 2022, 1:02 AM
ftynse added inline comments.Oct 6 2022, 1:26 AM
mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
121

It feels like having a separate builder for start and end using the normal builder.create would not be longer, but would be more robust...

mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
338
338

Nit: "pattern" is pretty strongly associated with a rewrite pattern, which this is not, consider a different term.

352
mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp
263

I think we are allowed to use MLIRSupport here, so prefer LogicalResult ot bools.

280–281

Nit: expand auto.

292–293

I don't see any check for this being an argument or a result name, so this error message is incorrect.

300–303

I'm confused about insertion here. The injected code, from what I can see, only calls Operation::create which only creates an detached operation but doesn't put it anywhere in the surrounding IR. One would normally need to push/splice it into some block, and I don't see where that would happen. But the test seems to pass... Can you point me to where the insertion happens?

313

Please expand auto here and everywhere else where the type is not clear from the immediate context, except for lambdas and annoyingly long types such as iterators.

gysit added inline comments.Oct 6 2022, 1:53 AM
mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
121

Ah that could be an interesting approach for all intrinsics. I could essentially, define a normal builder that constructs an MLIR LLVM dialect intrinsic given the LLVM IR call arguments? At least, if it is possible to define a builder on the intrinsic base class and then overwrite it for specific intrinsics.

mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp
300–303

If not mistaken, I did not change that part before and after the revision the code calls:

Operation *op = b.create(state);

I thought this actually inserts the operation at the current position.

Would it be preferable to call b.create<QualifiedCPPName>(...)? This would be possible in tablgen.

ftynse added inline comments.Oct 6 2022, 2:07 AM
mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
121

I meant for these two specifically, builder.create<LLVM::LifetimeStartOp>($_location, lookupIntegerAttr(inst->getArgOperand(0)), lookupValue(inst->getArgOperand(1))) looks more readable to an average MLIR user than going through OperationState. builder.create<LLVM::LifetimeStartOp>($_location, $_int_attr($size), $ptr) would be even more concise, but unclear if it's worth the complexity.

For the base class, you can likely call the default-generated builder function that takes a list of results, a list of operands and a list of attributes. Intrinsics that need attributes will have to override that or need some mechanism to tell the base class which ArgOperands correspond to which attribute names/types.

mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp
300–303

Oh, I missed that it was b.create, that does insert, thanks.

Yes, prefer using the templated version to populating the state manually. Also, at minimum document that "b" is an OpBuilder variable available in the builder snippet and that it is set up to the correct insertion point. Better yet, make it use $_builder instead and, internally, rename "b" to something that the user is less likely to clash with, like "odsBuilder".

gysit updated this revision to Diff 465717.Oct 6 2022, 7:04 AM
gysit marked 9 inline comments as done.

Address comments:

  • nicer builders
  • avoid auto
gysit added inline comments.Oct 6 2022, 7:09 AM
mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
121

I tried to implement the later solution. Operations with complex operands / attributes that differ too much from the LLVM implementation will still need a handwritten mapping from call instruction arguments to mlir builder arguments.

ftynse accepted this revision.Oct 7 2022, 1:10 AM
ftynse added inline comments.
mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
121

Nice!

This revision is now accepted and ready to land.Oct 7 2022, 1:10 AM