@@ -66,6 +66,14 @@ heavy::ExternFunction module_lookup;
6666
6767using namespace heavy ::mlir_helper;
6868
69+ static mlir::Location getMlirLocation (heavy::Context& C,
70+ heavy::SourceLocation Loc,
71+ mlir::MLIRContext* MC) {
72+ if (!Loc.isValid ())
73+ Loc = C.getLoc ();
74+ return mlir::OpaqueLoc::get (Loc.getOpaqueEncoding (), MC);
75+ }
76+
6977namespace heavy ::mlir_bind {
7078// Provide function to support create_op syntax.
7179// Require type checking as a precondition.
@@ -96,10 +104,7 @@ void create_op_impl(Context& C, ValueRefs Args) {
96104 mlir::OpBuilder* Builder = getCurrentBuilder (C);
97105 if (!Builder) return ;
98106
99- if (!Loc.isValid ())
100- Loc = C.getLoc ();
101- mlir::Location MLoc = mlir::OpaqueLoc::get (Loc.getOpaqueEncoding (),
102- Builder->getContext ());
107+ mlir::Location MLoc = getMlirLocation (C, Loc, Builder->getContext ());
103108 auto OpState = mlir::OperationState (MLoc, OpName);
104109
105110 // attributes
@@ -341,6 +346,28 @@ void entry_block(Context& C, ValueRefs Args) {
341346 C.Cont (C.CreateAny (Block));
342347}
343348
349+ // (add-argument block type loc)
350+ void add_argument (Context& C, ValueRefs Args) {
351+ if (Args.size () != 3 )
352+ return C.RaiseError (" invalid arity" );
353+ mlir::Block* Block = any_cast<mlir::Block*>(Args[0 ]);
354+ mlir::Type Type = any_cast<mlir::Type>(Args[1 ]);
355+ heavy::SourceLocation Loc= Args[2 ].getSourceLocation ();
356+ if (!Block)
357+ return C.RaiseError (" expecting mlir::Block*" , Args[0 ]);
358+ if (Type)
359+ return C.RaiseError (" expecting mlir::Block*" , Args[1 ]);
360+
361+ mlir::OpBuilder* Builder = getCurrentBuilder (C);
362+ if (!Builder)
363+ return ;
364+
365+ mlir::Location MLoc = getMlirLocation (C, Loc, Builder->getContext ());
366+ mlir::BlockArgument BA = Block->addArgument (Type, MLoc);
367+ heavy::Value Result = C.CreateAny (mlir::Value (BA));
368+ C.Cont (Result);
369+ }
370+
344371// Get list of results of op.
345372void results (Context& C, ValueRefs Args) {
346373 // This might be useful for applying to operations
@@ -459,24 +486,27 @@ void at_block_terminator(Context& C, ValueRefs Args) {
459486
460487// Set insertion point to prepend. (alters current-builder)
461488// (set-insertion-point _op_or_region_)
462- // Argument can be Operation, Region, or Block.
489+ // Argument can be Operation, Region
463490// Operation - Insert before operation in containing block.
464- // Region - Insert before operation in first block.
491+ // Region - Insert before any operation in first block.
465492void set_insertion_point (Context& C, ValueRefs Args) {
466493 if (Args.size () != 1 )
467494 return C.RaiseError (" invalid arity" );
468495
469496 mlir::OpBuilder* Builder = getCurrentBuilder (C);
470497 if (!Builder) return ;
471498
472- if (auto * Op = dyn_cast<mlir::Operation>(Args[0 ]))
499+ if (auto * Op = dyn_cast<mlir::Operation>(Args[0 ])) {
500+ // Insert before the operation.
473501 Builder->setInsertionPoint (Op);
474- else if (mlir::Region* R = any_cast<mlir::Region*>(Args[0 ])) {
502+ } else if (mlir::Region* R = any_cast<mlir::Region*>(Args[0 ])) {
475503 // Automatically add block if needed.
476504 if (R->empty ())
477505 R->emplaceBlock ();
478506 mlir::Block* Block = &R->front ();
479507 Builder->setInsertionPointToStart (Block);
508+ } else {
509+ return C.RaiseError (" expecting mlir.op or mlir.region" , Args[0 ]);
480510 }
481511 C.Cont ();
482512}
0 commit comments