Skip to content

Commit 6ddaa68

Browse files
committed
[Heavy] Add LoadModuleOp for runtime dependency graph
1 parent bd9564c commit 6ddaa68

File tree

7 files changed

+52
-11
lines changed

7 files changed

+52
-11
lines changed

heavy/include/heavy/Ops.td

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,22 @@ def heavy_LoadGlobalOp : HeavyOp<"load_global"> {
275275
];
276276
}
277277

278+
def heavy_LoadModuleOp : HeavyOp<"load_module"> {
279+
let summary = "load_module";
280+
let description = [{
281+
Load a module by its mangled name and initialize it.
282+
This also enables the creation of a runtime dependency graph
283+
for exporting to bytecode files.
284+
}];
285+
286+
let arguments = (ins FlatSymbolRefAttr:$name);
287+
let results = (outs);
288+
289+
let builders = [
290+
OpBuilder<(ins "::llvm::StringRef":$name)>
291+
];
292+
}
293+
278294
def heavy_ExportOp : HeavyOp<"export", [Symbol, IsolatedFromAbove,
279295
NoTerminator]> {
280296
let summary = "export";

heavy/lib/Builtins.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,10 @@ void compile(Context& C, ValueRefs Args) {
692692
return;
693693
}
694694

695+
// Clear any errors in the compiler too keep the dream alive.
696+
if (heavy::OpGen* OpGen = Env->GetOpGen())
697+
OpGen->ClearError();
698+
695699
// If there is a provided handler then we save the results in an
696700
// improper, reversed ordered list (stack) to pass to the handler.
697701
Value ResultHandler = Undefined();

heavy/lib/Context.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,8 @@ namespace {
871871
llvm::SmallVectorImpl<char>& Output) {
872872
llvm::StringRef ModulePath =
873873
HEAVY_BASE_VAR(module_path).get(C).getStringRef();
874-
llvm::Twine(ModulePath, "/").toVector(Output);
874+
if (!ModulePath.empty())
875+
llvm::Twine(ModulePath, "/").toVector(Output);
875876

876877
llvm::StringRef Input = MangledName;
877878
Input.consume_front(Mangler::getManglePrefix());

heavy/lib/Dialect.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ void LoadGlobalOp::build(mlir::OpBuilder& B, mlir::OperationState& OpState,
160160
LoadGlobalOp::build(B, OpState, HeavyValueT, SymName);
161161
}
162162

163+
void LoadModuleOp::build(mlir::OpBuilder& B, mlir::OperationState& OpState,
164+
llvm::StringRef SymName) {
165+
LoadModuleOp::build(B, OpState, {}, SymName);
166+
}
167+
163168
void MatchOp::build(mlir::OpBuilder& B, mlir::OperationState& OpState,
164169
heavy::Value val, mlir::Value input) {
165170
assert((!isa<Pair, Vector>(val)) && "expected non-structural constant");

heavy/lib/OpEval.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class OpEvalImpl {
9595
}
9696

9797
void Eval(mlir::Operation* Op) {
98-
if (isa<GlobalOp, CommandOp>(Op)) {
98+
if (isa<GlobalOp, CommandOp, LoadModuleOp>(Op)) {
9999
BlockItrTy Itr = Visit(Op);
100100

101101
if (Itr == BlockItrTy())
@@ -192,7 +192,6 @@ class OpEvalImpl {
192192
if (isa<BindingOp>(Op)) return Visit(cast<BindingOp>(Op));
193193
else if (isa<LiteralOp>(Op)) return Visit(cast<LiteralOp>(Op));
194194
else if (isa<ApplyOp>(Op)) return Visit(cast<ApplyOp>(Op));
195-
//else if (isa<BuiltinOp>(Op)) return Visit(cast<BuiltinOp>(Op));
196195
else if (isa<ContOp>(Op)) return Visit(cast<ContOp>(Op));
197196
else if (isa<GlobalOp>(Op)) return Visit(cast<GlobalOp>(Op));
198197
else if (isa<LoadClosureOp>(Op)) return Visit(cast<LoadClosureOp>(Op));
@@ -213,6 +212,7 @@ class OpEvalImpl {
213212
else if (isa<RenameOp>(Op)) return Visit(cast<RenameOp>(Op));
214213
else if (isa<ToVectorOp>(Op)) return Visit(cast<ToVectorOp>(Op));
215214
else if (isa<VectorOp>(Op)) return Visit(cast<VectorOp>(Op));
215+
else if (isa<LoadModuleOp>(Op)) return Visit(cast<LoadModuleOp>(Op));
216216
else if (isa<SyntaxClosureOp>(Op))
217217
return Visit(cast<SyntaxClosureOp>(Op));
218218
else if (isa<SourceLocOp>(Op)) return Visit(cast<SourceLocOp>(Op));
@@ -485,6 +485,19 @@ class OpEvalImpl {
485485
return next(Op);
486486
}
487487

488+
BlockItrTy Visit(LoadModuleOp Op) {
489+
heavy::Symbol* ModuleName = Context.CreateSymbol(Op.getName());
490+
Context.PushCont([](heavy::Context& C, ValueRefs) {
491+
heavy::Symbol* ModuleName = cast<Symbol>(C.getCapture(0));
492+
C.PushCont([](heavy::Context& C, ValueRefs) {
493+
heavy::Symbol* ModuleName = cast<Symbol>(C.getCapture(0));
494+
C.InitModule(ModuleName);
495+
}, CaptureList{ModuleName});
496+
C.LoadModule(ModuleName);
497+
}, CaptureList{ModuleName});
498+
return BlockItrTy();
499+
}
500+
488501
BlockItrTy Visit(LoadGlobalOp Op) {
489502
Value Val = Context.GetKnownValue(Op.getName());
490503
if (!Val) {

heavy/lib/OpGen.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,8 @@ mlir::ModuleOp OpGen::getModuleOp() {
9090

9191
void OpGen::createLoadModule(heavy::SourceLocation Loc,
9292
heavy::Symbol* MangledName) {
93-
mlir::Value Fn = createGlobal(Loc, HEAVY_LOAD_MODULE_VAR);
94-
mlir::Value LiteralOp = createLiteral(MangledName);
95-
mlir::Value Args[] = {LiteralOp};
96-
createCall(Loc, Fn, Args);
97-
// We only want this evaluated when loading stand-alone bytecode files.
98-
FinishTopLevelOp();
93+
TopLevelOp = createHelper<heavy::LoadModuleOp>(ModuleBuilder, Loc,
94+
MangledName->getStringRef());
9995
}
10096

10197
mlir::Value OpGen::GetSingleResult(heavy::Value V) {
@@ -316,7 +312,8 @@ void OpGen::VisitTopLevel(Value V) {
316312
}
317313

318314
void OpGen::FinishTopLevelOp() {
319-
assert((TopLevelOp == nullptr || isa<CommandOp, GlobalOp>(TopLevelOp)) &&
315+
assert((TopLevelOp == nullptr ||
316+
isa<CommandOp, GlobalOp, LoadModuleOp>(TopLevelOp)) &&
320317
"Top level operation must be CommandOp or GlobalOp");
321318

322319
if (heavy::CommandOp CommandOp =
@@ -920,10 +917,14 @@ mlir::Value OpGen::createGlobal(SourceLocation Loc,
920917
auto GlobalOp = cast<heavy::GlobalOp>(G);
921918

922919
// Localize globals by the GlobalOp's Operation*
923-
mlir::Value LocalV = BindingTable.lookup(CanonicalValue);
920+
mlir::Value LocalV;
921+
// If no TopLevelOp exists then no binding scope exists either.
922+
if (TopLevelOp)
923+
LocalV = BindingTable.lookup(CanonicalValue);
924924
if (!LocalV) {
925925
LocalV = create<LoadGlobalOp>(Loc, GlobalOp.getName());
926926
BindingTable.insert(CanonicalValue, LocalV);
927+
return LocalV;
927928
}
928929

929930
return LocalizeValue(LocalV, CanonicalValue);

heavy/test/Evaluate/Inputs/my/lib.sld

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
(import (heavy base))
22
(define-library (my lib)
33
(import (heavy base))
4+
(import (heavy mlir))
45
(begin
56
(define (hello-module x)
67
(write "hello module!")

0 commit comments

Comments
 (0)