Adding `vm.select.ref` lowering to emitc.
diff --git a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/ConvertVMToEmitC.cpp b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/ConvertVMToEmitC.cpp index 5eef577..9df179f 100644 --- a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/ConvertVMToEmitC.cpp +++ b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/ConvertVMToEmitC.cpp
@@ -1063,7 +1063,6 @@ if (typeName[0] == '!') { typeName = typeName.substr(1); } - typeName = std::string("\"") + typeName + std::string("\""); Value stringView = emitc_builders::ireeMakeCstringView(builder, loc, typeName); @@ -2947,6 +2946,107 @@ } }; +class SelectRefOpConversion + : public EmitCConversionPattern<IREE::VM::SelectRefOp> { + using Adaptor = typename IREE::VM::SelectRefOp::Adaptor; + using EmitCConversionPattern<IREE::VM::SelectRefOp>::EmitCConversionPattern; + + LogicalResult + matchAndRewrite(IREE::VM::SelectRefOp selectOp, Adaptor adaptor, + ConversionPatternRewriter &rewriter) const override { + auto ctx = selectOp.getContext(); + auto loc = selectOp.getLoc(); + + auto moduleOp = + selectOp.getOperation()->template getParentOfType<IREE::VM::ModuleOp>(); + auto funcOp = selectOp.getOperation() + ->template getParentOfType<mlir::emitc::FuncOp>(); + auto &funcAnalysis = getModuleAnalysis().lookupFunction(funcOp); + + const BlockArgument moduleArg = funcOp.getArgument(CCONV_ARGUMENT_MODULE); + auto resultTypePtr = + createVmTypeDefPtr(rewriter, loc, this->getModuleAnalysis(), moduleOp, + moduleArg, selectOp.getType()); + if (!resultTypePtr.has_value()) { + return selectOp->emitError() << "generating iree_vm_type_def_t* failed"; + } + auto resultTypeAsRef = + rewriter + .create<emitc::CallOpaqueOp>( + /*location=*/loc, + /*type=*/emitc::OpaqueType::get(ctx, "iree_vm_ref_type_t"), + /*callee=*/StringAttr::get(ctx, "iree_vm_type_def_as_ref"), + /*args=*/ArrayAttr{}, /*templateArgs=*/ArrayAttr{}, + /*operands=*/ArrayRef<Value>{resultTypePtr.value()}) + .getResult(0); + + bool moveTrue = + funcAnalysis.isMove(selectOp.getTrueValue(), selectOp.getOperation()); + bool moveFalse = + funcAnalysis.isMove(selectOp.getFalseValue(), selectOp.getOperation()); + + Value refTrue = + this->getModuleAnalysis().lookupRef(selectOp.getTrueValue()); + Value refFalse = + this->getModuleAnalysis().lookupRef(selectOp.getFalseValue()); + Value refResult = this->getModuleAnalysis().lookupRef(selectOp.getResult()); + + Type boolType = rewriter.getI1Type(); + auto condition = rewriter.create<IREE::VM::CmpNZI32Op>( + loc, rewriter.getI32Type(), selectOp.getCondition()); + auto conditionI1 = rewriter.create<emitc::CastOp>( + /*location=*/loc, + /*type=*/boolType, + /*operand=*/condition.getResult()); + + auto *continueBlock = + rewriter.splitBlock(selectOp->getBlock(), Block::iterator(selectOp)); + + Block *trueBlock = nullptr; + { + OpBuilder::InsertionGuard guard(rewriter); + trueBlock = rewriter.createBlock(continueBlock); + returnIfError( + /*rewriter=*/rewriter, + /*location=*/loc, + /*callee=*/StringAttr::get(ctx, "iree_vm_ref_retain_or_move_checked"), + /*args=*/ + ArrayAttr::get( + ctx, {rewriter.getBoolAttr(moveTrue), rewriter.getIndexAttr(0), + rewriter.getIndexAttr(1), rewriter.getIndexAttr(2)}), + /*operands=*/ + ArrayRef<Value>{refTrue, resultTypeAsRef, refResult}, + this->getModuleAnalysis()); + rewriter.create<IREE::VM::BranchOp>(loc, continueBlock); + } + + Block *falseBlock = nullptr; + { + OpBuilder::InsertionGuard guard(rewriter); + falseBlock = rewriter.createBlock(continueBlock); + returnIfError( + /*rewriter=*/rewriter, + /*location=*/loc, + /*callee=*/StringAttr::get(ctx, "iree_vm_ref_retain_or_move_checked"), + /*args=*/ + ArrayAttr::get( + ctx, {rewriter.getBoolAttr(moveFalse), rewriter.getIndexAttr(0), + rewriter.getIndexAttr(1), rewriter.getIndexAttr(2)}), + /*operands=*/ + ArrayRef<Value>{refFalse, resultTypeAsRef, refResult}, + this->getModuleAnalysis()); + rewriter.create<IREE::VM::BranchOp>(loc, continueBlock); + } + + rewriter.setInsertionPointAfterValue(conditionI1); + rewriter.create<mlir::cf::CondBranchOp>(loc, conditionI1.getResult(), + trueBlock, falseBlock); + rewriter.replaceOp(selectOp, refResult); + + return success(); + } +}; + template <typename OpTy> class ConstOpConversion : public EmitCConversionPattern<OpTy> { using Adaptor = typename OpTy::Adaptor; @@ -3429,12 +3529,8 @@ releaseRefs(rewriter, loc, funcOp, getModuleAnalysis()); - std::string messageStr = std::string("\"") + - op.getMessage().value_or("").str() + - std::string("\""); - - Value message = - emitc_builders::ireeMakeCstringView(rewriter, loc, messageStr); + Value message = emitc_builders::ireeMakeCstringView( + rewriter, loc, op.getMessage().value_or("").str()); auto messageSizeOp = emitc_builders::structMember( rewriter, loc, @@ -4430,6 +4526,7 @@ CallOpConversion<IREE::VM::CallOp>, CallOpConversion<IREE::VM::CallVariadicOp>, CompareRefNotZeroOpConversion, + SelectRefOpConversion, CondBranchOpConversion, BranchTableOpConversion, ConstOpConversion<IREE::VM::ConstF32Op>,
diff --git a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/EmitCBuilders.cpp b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/EmitCBuilders.cpp index e817f9e..3076f2d 100644 --- a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/EmitCBuilders.cpp +++ b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/EmitCBuilders.cpp
@@ -299,6 +299,11 @@ Value ireeMakeCstringView(OpBuilder builder, Location location, std::string str) { + std::string escapedStr; + llvm::raw_string_ostream os(escapedStr); + os.write_escaped(str); + auto quotedStr = std::string("\"") + escapedStr + std::string("\""); + auto ctx = builder.getContext(); return builder .create<emitc::CallOpaqueOp>( @@ -306,7 +311,7 @@ /*type=*/emitc::OpaqueType::get(ctx, "iree_string_view_t"), /*callee=*/StringAttr::get(ctx, "iree_make_cstring_view"), /*args=*/ - ArrayAttr::get(ctx, {emitc::OpaqueAttr::get(ctx, str)}), + ArrayAttr::get(ctx, {emitc::OpaqueAttr::get(ctx, quotedStr)}), /*templateArgs=*/ArrayAttr{}, /*operands=*/ArrayRef<Value>{}) .getResult(0);
diff --git a/runtime/src/iree/vm/test/assignment_ops.mlir b/runtime/src/iree/vm/test/assignment_ops.mlir index 1388c1e..891165d 100644 --- a/runtime/src/iree/vm/test/assignment_ops.mlir +++ b/runtime/src/iree/vm/test/assignment_ops.mlir
@@ -17,7 +17,7 @@ vm.return } - vm.export @test_select_ref attributes {emitc.exclude} + vm.export @test_select_ref vm.func private @test_select_ref() { %c0 = vm.const.i32 0 %list0 = vm.list.alloc %c0 : (i32) -> !vm.list<i8>