How can I take the value of an operation? Then print it

This is my first time writing a pass in mlir,I have encountered some problems.Here are the results of my opt run.

module {
  func.func @fun() {
    %c0_i64 = arith.constant 0 : i64
    gemmini.ConfigSt %c0_i64 : i64
    return
  }
}

This is my matchAndRewrite.Stride is an alias for the configSt parameter.So I can call getStride.But I want to take out the 0 in %c0_i64 = arith.constant 0 : i64,then do some calculations,but I don’t know how to do it,I tried for a long time.

LogicalResult
  matchAndRewrite(ConfigStOp configStOp, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    mlir::Value stride = configStOp.getStride();
    
    return success();
  }

On the other hand.I want to use rewriter.create to create a value,but the value is just a number.I don’t know what to do.I think for the two questions above, mainly because I don’t know the relevant information, is there any relevant information here that I can study?If anyone can help me, I would be grateful.Thanks!

cast<arith::ConstantOp>(configStOp.getStride().getDefiningOp()).getValue()

I highly recommend you follow the toy tutorial and Understanding the IR Structure - MLIR

You need to create an operation, such as a constant-like operation, that defines an SSA value out of an attribute. “Plain” values can be wrapped into attributes.

1 Like

You have solved my problem again, thank you.

I seem to have encountered a new problem.This is my pass.But I found it can’t lower.

LogicalResult
matchAndRewrite(ConfigStOp configStOp, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    mlir::Type i64Type = rewriter.getI64Type();
    mlir::Attribute input0 = rewriter.getI64IntegerAttr(111111); 
    mlir::Location loc = configStOp.getLoc(); 
    mlir::Attribute input1 = rewriter.getI64IntegerAttr(123456);
    mlir::Value value1 = rewriter.create<arith::ConstantOp>(loc, input0, i64Type);
    mlir::Value value2 = rewriter.create<arith::ConstantOp>(loc, input1, i64Type);
    auto context = configStOp.getContext();
    rewriter.replaceOpWithNewOp<ConfigSt_IntrOp>(configStOp, value1, value2);
    return success();
  }

When i run opt,it show that.

configSt.mlir:3:3: error: failed to legalize operation 'gemmini.ConfigSt' that was explicitly marked illegal
  gemmini.ConfigSt %0 : i64 
  ^
configSt.mlir:3:3: note: see current operation: "gemmini.ConfigSt"(%0) : (i64) -> ()

If I remove the following code.

target.addLegalOp<ConfigSt_IntrOp>();
target.addIllegalOp<ConfigStOp>();

When I run the opt again.It show that.

$: opt configSt.mlir  --lower-gemmini
module {
  func.func @fun() {
    %c0_i64 = arith.constant 0 : i64
    gemmini.ConfigSt %c0_i64 : i64
    return
  }
}

It doesn’t seem to create the arith::constantop in my pass and my pass did not work.I don’t know what the problem is.

What is reported when you add --debug option to command line? (You’ll need to not built with NDEBUG set to have that option shown, easiest is to use debug build config).

1 Like

I’ve solved the problem by looking at the debug messages, thanks!

$ configSt.mlir  --lower-gemmini --debug
Args: ../../build1/bin/buddy-opt configSt.mlir --lower-gemmini --debug 
Load new dialect in Context builtin
ImplicitTypeIDRegistry::lookupOrInsert(mlir::SubElementTypeInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::ShapedType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::MemRefLayoutAttrInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::SubElementAttrInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::ElementsAttr)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::TypedAttr)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::SymbolOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpAsmOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::RegionKindInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::CastOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::ConditionallySpeculatable)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::MemoryEffectOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::ResourceBlobManagerDialectInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpAsmDialectInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::BytecodeDialectInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::detail::AffineBinaryOpExprStorage)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::detail::AffineConstantExprStorage)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::detail::AffineDimExprStorage)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::detail::AffineMapStorage)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::detail::IntegerSetStorage)
Load new dialect in Context builtin
ImplicitTypeIDRegistry::lookupOrInsert(mlir::DebugActionManager::GenericHandler)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::ZeroOperands<mlir::TypeID::get() [with Trait = mlir::OpTrait::ZeroOperands]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::OneRegion<mlir::TypeID::get() [with Trait = mlir::OpTrait::OneRegion]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::ZeroResults<mlir::TypeID::get() [with Trait = mlir::OpTrait::ZeroResults]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::ZeroSuccessors<mlir::TypeID::get() [with Trait = mlir::OpTrait::ZeroSuccessors]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::NoRegionArguments<mlir::TypeID::get() [with Trait = mlir::OpTrait::NoRegionArguments]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::NoTerminator<mlir::TypeID::get() [with Trait = mlir::OpTrait::NoTerminator]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::SingleBlock<mlir::TypeID::get() [with Trait = mlir::OpTrait::SingleBlock]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::OpInvariants<mlir::TypeID::get() [with Trait = mlir::OpTrait::OpInvariants]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::AffineScope<mlir::TypeID::get() [with Trait = mlir::OpTrait::AffineScope]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::IsIsolatedFromAbove<mlir::TypeID::get() [with Trait = mlir::OpTrait::IsIsolatedFromAbove]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::SymbolTable<mlir::TypeID::get() [with Trait = mlir::OpTrait::SymbolTable]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::SymbolOpInterface::Trait<mlir::TypeID::get() [with Trait = mlir::SymbolOpInterface::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpAsmOpInterface::Trait<mlir::TypeID::get() [with Trait = mlir::OpAsmOpInterface::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::RegionKindInterface::Trait<mlir::TypeID::get() [with Trait = mlir::RegionKindInterface::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::HasOnlyGraphRegion<mlir::TypeID::get() [with Trait = mlir::OpTrait::HasOnlyGraphRegion]::Empty>)
Load new dialect in Context func
Load new dialect in Context cf
Load new dialect in Context arith
ImplicitTypeIDRegistry::lookupOrInsert(mlir::arith::ArithFastMathInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::VectorUnrollOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::InferTypeOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::InferIntRangeInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::DialectInlinerInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::bufferization::BufferizableOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::BranchOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::CallOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::SymbolUserOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::CallableOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::FunctionOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::AutomaticAllocationScope<mlir::TypeID::get() [with Trait = mlir::OpTrait::AutomaticAllocationScope]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::CallableOpInterface::Trait<mlir::TypeID::get() [with Trait = mlir::CallableOpInterface::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::FunctionOpInterface::Trait<mlir::TypeID::get() [with Trait = mlir::FunctionOpInterface::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::ZeroRegions<mlir::TypeID::get() [with Trait = mlir::OpTrait::ZeroRegions]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::OneResult<mlir::TypeID::get() [with Trait = mlir::OpTrait::OneResult]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::OneTypedResult<mlir::Type>::Impl<mlir::TypeID::get() [with Trait = mlir::OpTrait::OneTypedResult<mlir::Type>::Impl]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::ConstantLike<mlir::TypeID::get() [with Trait = mlir::OpTrait::ConstantLike]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::ConditionallySpeculatable::Trait<mlir::TypeID::get() [with Trait = mlir::ConditionallySpeculatable::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::AlwaysSpeculatableImplTrait<mlir::TypeID::get() [with Trait = mlir::OpTrait::AlwaysSpeculatableImplTrait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::MemoryEffectOpInterface::Trait<mlir::TypeID::get() [with Trait = mlir::MemoryEffectOpInterface::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::InferIntRangeInterface::Trait<mlir::TypeID::get() [with Trait = mlir::InferIntRangeInterface::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::InferTypeOpInterface::Trait<mlir::TypeID::get() [with Trait = mlir::InferTypeOpInterface::Trait]::Empty>)
Load new dialect in Context gemmini
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::OneOperand<mlir::TypeID::get() [with Trait = mlir::OpTrait::OneOperand]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::VariadicOperands<mlir::TypeID::get() [with Trait = mlir::OpTrait::VariadicOperands]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::HasParent<mlir::func::FuncOp>::Impl<mlir::TypeID::get() [with Trait = mlir::OpTrait::HasParent<mlir::func::FuncOp>::Impl]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::MemRefsNormalizable<mlir::TypeID::get() [with Trait = mlir::OpTrait::MemRefsNormalizable]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::ReturnLike<mlir::TypeID::get() [with Trait = mlir::OpTrait::ReturnLike]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::IsTerminator<mlir::TypeID::get() [with Trait = mlir::OpTrait::IsTerminator]::Empty>)
Load new dialect in Context llvm
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMVoidType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMPPCFP128Type)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMX86MMXType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMTokenType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMLabelType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMMetadataType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMStructType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::DataLayoutTypeInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::FastmathFlagsInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::detail::OpToOpPassAdaptor)

//===-------------------------------------------===//
Legalizing operation : 'builtin.module'(0x56129ce72e90) {
  * Fold {
ImplicitTypeIDRegistry::lookupOrInsert(mlir::DialectFoldInterface)
  } -> FAILURE : unable to fold
} -> FAILURE : no matched legalization pattern
//===-------------------------------------------===//

//===-------------------------------------------===//
Legalizing operation : 'func.func'(0x56129ceac680) {
  * Fold {
  } -> FAILURE : unable to fold
} -> FAILURE : no matched legalization pattern
//===-------------------------------------------===//

//===-------------------------------------------===//
Legalizing operation : 'arith.constant'(0x56129ce8e530) {
  %0 = "arith.constant"() {value = 0 : i64} : () -> i64

  * Fold {
  } -> FAILURE : unable to fold
} -> FAILURE : no matched legalization pattern
//===-------------------------------------------===//

//===-------------------------------------------===//
Legalizing operation : 'gemmini.ConfigSt'(0x56129cea9cf0) {
  "gemmini.ConfigSt"(%0) : (i64) -> ()

  * Fold {
  } -> FAILURE : unable to fold

  * Pattern : 'gemmini.ConfigSt -> ()' {
Trying to match "GemminiConfigStOpLowering"
    ** Insert  : 'arith.constant'(0x56129ceace00)
    ** Insert  : 'arith.constant'(0x56129ced6390)
    ** Insert  : 'gemmini.intr.configSt'(0x56129ced63e0)
    ** Replace : 'gemmini.ConfigSt'(0x56129cea9cf0)
"GemminiConfigStOpLowering" result 1

    //===-------------------------------------------===//
    Legalizing operation : 'arith.constant'(0x56129ceace00) {
      %1 = "arith.constant"() {value = 111111 : i64} : () -> i64

      * Fold {
      } -> FAILURE : unable to fold
    } -> FAILURE : no matched legalization pattern
    //===-------------------------------------------===//
  } -> FAILURE : failed to legalize generated operation 'arith.constant'(0x000056129CEACE00)
} -> FAILURE : pattern failed to match
} -> FAILURE : no matched legalization pattern

Create, notifyRewriteFailure is very useful in patterns in conjunction with debug flag for cases where pattern only sometimes apply.