Repository navigation
Expand file tree
/
Copy pathCompilerFront.cpp
More file actions
127 lines (104 loc) · 3.97 KB
/
Copy pathCompilerFront.cpp
File metadata and controls
127 lines (104 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// SPDX-FileCopyrightText: 2024 The HC Authors
// SPDX-FileCopyrightText: 2025 The HC Authors
//
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include <llvm/ADT/SmallString.h>
#include <llvm/ADT/StringRef.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/SourceMgr.h>
#include <mlir/Dialect/Arith/IR/Arith.h>
#include <mlir/IR/Builders.h>
#include <mlir/IR/BuiltinOps.h>
#include <mlir/IR/Verifier.h>
#include <mlir/InitAllDialects.h>
#include <mlir/Pass/PassManager.h>
#include <mlir/Support/FileUtilities.h>
#include <mlir/Support/LogicalResult.h>
#include <mlir/Tools/mlir-opt/MlirOptMain.h>
#include "hc/Dialect/HKernel/IR/HKernelOps.hpp"
#include "hc/Dialect/PyAST/IR/PyASTOps.hpp"
#include "hc/Dialect/PyIR/IR/PyIROps.hpp"
#include "hc/Dialect/Typing/IR/TypingOps.hpp"
#include "hc/PyFront/Import.hpp"
#include "CompilerFront.hpp"
#include "Context.hpp"
#include "Utils.hpp"
static void createModuleImport(mlir::OpBuilder &builder,
const ImportedSym &sym) {
assert(!sym.modulePath.empty());
mlir::Value mod;
mlir::Location loc = builder.getUnknownLoc();
auto type = hc::py_ir::UndefinedType::get(builder.getContext());
for (auto &&path : sym.modulePath) {
if (!mod) {
mod = builder.create<hc::py_ir::LoadModuleOp>(loc, type, path);
continue;
}
mod = builder.create<hc::py_ir::GetAttrOp>(loc, type, mod, path);
}
assert(mod);
builder.create<hc::py_ir::StoreVarOp>(loc, sym.name, mod);
}
template <typename T> static std::string toStr(T &&val) {
std::string ret;
llvm::raw_string_ostream os(ret);
os << val;
os.flush();
return ret;
}
static void createLiteral(mlir::OpBuilder &builder, const Literal &lit) {
auto attr = mlir::cast<mlir::TypedAttr>(lit.attr);
auto loc = builder.getUnknownLoc();
// TODO: refac
if (auto typeAttr = mlir::dyn_cast<hc::typing::TypeAttr>(attr)) {
if (auto sym = mlir::dyn_cast<hc::typing::SymbolicTypeBase>(
typeAttr.getTypeVal())) {
mlir::Value val = builder.create<hc::hk::MaterializeExprOp>(loc, sym);
builder.create<hc::py_ir::StoreVarOp>(loc, lit.name, val);
return;
}
}
auto op =
attr.getDialect().materializeConstant(builder, attr, attr.getType(), loc);
if (!op) {
auto arith =
attr.getContext()->getLoadedDialect<mlir::arith::ArithDialect>();
op = arith->materializeConstant(builder, attr, attr.getType(), loc);
}
if (!op)
reportError(llvm::Twine("Cannot materialize literal: ") + toStr(lit.attr));
builder.create<hc::py_ir::StoreVarOp>(loc, lit.name, op->getResult(0));
}
static mlir::LogicalResult
importAST(mlir::Operation *mod, llvm::StringRef source,
llvm::StringRef funcName, llvm::ArrayRef<ImportedSym> importedSymbols,
llvm::ArrayRef<Literal> literals, bool dumpAST) {
auto res = hc::importPyModule(source, mod, dumpAST);
if (mlir::failed(res))
return mlir::failure();
auto pyMod = mlir::cast<hc::py_ast::PyModuleOp>(*res);
mlir::OpBuilder builder(mod->getContext());
mlir::Block *body = pyMod.getBody();
builder.setInsertionPointToStart(body);
for (auto &&sym : importedSymbols)
createModuleImport(builder, sym);
for (auto &&lit : literals)
createLiteral(builder, lit);
auto term = body->getTerminator();
builder.setInsertionPoint(term);
builder.create<hc::py_ast::CaptureValOp>(term->getLoc(), funcName);
return mlir::success();
}
mlir::FailureOr<mlir::OwningOpRef<mlir::Operation *>>
compileAST(Context &ctx, llvm::StringRef source, llvm::StringRef funcName,
llvm::ArrayRef<ImportedSym> importedSymbols,
llvm::ArrayRef<Literal> literals) {
auto *mlirContext = &ctx.context;
auto loc = mlir::OpBuilder(mlirContext).getUnknownLoc();
mlir::OwningOpRef<mlir::Operation *> mod(mlir::ModuleOp::create(loc));
auto &settings = ctx.settings;
if (mlir::failed(importAST(*mod, source, funcName, importedSymbols, literals,
settings.dumpAST)))
return mlir::failure();
return mod;
}