Moving to the a JIT first design
I realized that focusing on SLIR at this stage is wrong. I need to finish up the JIT first and use the JIT to implement `read`, `eval` and `print` functions by linking their C++ implementations via a static library to the target code and then focus on SLIR or any alternative that might come next. This is the finish linke for the `0.x` version series.
This commit is contained in:
parent
3f025a1a85
commit
f436d6cee4
2
dev.org
2
dev.org
|
@ -36,6 +36,8 @@ Then here is the list or parsers that we have considered
|
|||
- [[http://www.lispworks.com/documentation/HyperSpec/Body/02_df.htm][Backquote in CL]]
|
||||
- [[https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node367.html][Backquote spec in Common Lisp the Language, 2nd Edition]]
|
||||
- [[http://christophe.rhodes.io/notes/blog/posts/2014/backquote_and_pretty_printing/][Backquote and pretty printing]]
|
||||
*** Compilers
|
||||
- https://bernsteinbear.com/blog/compiling-a-lisp-0/
|
||||
** Rust
|
||||
- [[https://doc.rust-lang.org/book/][The Rust book]] (in [[https://www.reddit.com/r/rust/comments/2s1zj2/the_rust_programming_language_book_as_epub/][EPUB]] format)
|
||||
** LLVM
|
||||
|
|
|
@ -26,13 +26,13 @@
|
|||
#include <string>
|
||||
|
||||
namespace serene {
|
||||
static std::string mangleInternalStringName(llvm::StringRef str) {
|
||||
return "__serene__internal__str__" + str.str();
|
||||
}
|
||||
// static std::string mangleInternalStringName(llvm::StringRef str) {
|
||||
// return "__serene__internal__str__" + str.str();
|
||||
// }
|
||||
|
||||
static std::string mangleInternalSymName(llvm::StringRef str) {
|
||||
return "__serene__symbol__" + str.str();
|
||||
}
|
||||
// static std::string mangleInternalSymName(llvm::StringRef str) {
|
||||
// return "__serene__symbol__" + str.str();
|
||||
// }
|
||||
|
||||
} // namespace serene
|
||||
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
set(LLVM_TARGET_DEFINITIONS dialect.td)
|
||||
mlir_tablegen(ops.h.inc -gen-op-decls)
|
||||
mlir_tablegen(ops.cpp.inc -gen-op-defs)
|
||||
mlir_tablegen(types.h.inc -gen-typedef-decls)
|
||||
|
||||
mlir_tablegen(attrs.h.inc -gen-attrdef-decls)
|
||||
mlir_tablegen(attrs.cpp.inc -gen-attrdef-defs)
|
||||
mlir_tablegen(types.h.inc -gen-typedef-decls )
|
||||
mlir_tablegen(types.cpp.inc -gen-typedef-defs)
|
||||
|
||||
mlir_tablegen(dialect.h.inc -gen-dialect-decls)
|
||||
mlir_tablegen(dialect.cpp.inc -gen-dialect-defs)
|
||||
add_public_tablegen_target(SereneDialectGen)
|
||||
|
|
|
@ -80,6 +80,35 @@ def ValueOp : Serene_Op<"value", [
|
|||
let hasFolder = 1;
|
||||
}
|
||||
|
||||
// serene.intern
|
||||
def InternOp : Serene_Op<"intern", [
|
||||
NoSideEffect
|
||||
]> {
|
||||
|
||||
let summary = "This operation is the runtime contructor for symbol type";
|
||||
let description = [{
|
||||
The `intern` operation produces an SSA value that holds a value of type
|
||||
symbol at runtime.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
|
||||
%ns = serene.string "some.ns"
|
||||
%name = serene.string "symbol_name"
|
||||
%1 = serene.intern %ns %name
|
||||
|
||||
// Equivalent generic form
|
||||
%1 = "serene.symbol"(%ns, %name){} : (!serene.string, !serene.string) -> !serene.ptr<serene.symbol>
|
||||
```
|
||||
}];
|
||||
|
||||
let arguments = (ins StringType:$ns, StringType:$name);
|
||||
let results = (outs Ptr<SymbolType>:$result);
|
||||
|
||||
let assemblyFormat = "attr-dict $ns $name";
|
||||
}
|
||||
|
||||
// serene.symbol
|
||||
def SymbolOp : Serene_Op<"symbol", [
|
||||
NoSideEffect, ConstantLike,
|
||||
|
@ -101,10 +130,11 @@ def SymbolOp : Serene_Op<"symbol", [
|
|||
```
|
||||
}];
|
||||
|
||||
let arguments = (ins StrAttr:$ns, StrAttr:$name);
|
||||
let results = (outs SymbolType:$result);
|
||||
let arguments = (ins SymbolAttr:$value);
|
||||
let results = (outs Ptr<SymbolType>:$result);
|
||||
|
||||
let assemblyFormat = "attr-dict $ns $name";
|
||||
let assemblyFormat = "attr-dict $value";
|
||||
let hasFolder = 1;
|
||||
}
|
||||
|
||||
// serene.convert
|
||||
|
@ -119,7 +149,7 @@ def ConvertOp : Serene_Op<"convert", [
|
|||
|
||||
let arguments = (ins AnyType:$value);
|
||||
|
||||
let results = (outs Ptr<SymbolType>:$result);
|
||||
let results = (outs AnyType:$result);
|
||||
|
||||
let assemblyFormat = [{
|
||||
$value attr-dict `:` functional-type($value, results)
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#include <mlir/IR/DialectImplementation.h>
|
||||
#include <mlir/IR/TypeSupport.h>
|
||||
|
||||
#define GET_ATTRDEF_CLASSES
|
||||
#include "serene/slir/attrs.h.inc"
|
||||
|
||||
#define GET_TYPEDEF_CLASSES
|
||||
#include "serene/slir/types.h.inc"
|
||||
|
||||
|
|
|
@ -20,10 +20,35 @@
|
|||
#define SERENE_DIALECT_TYPES_TD
|
||||
|
||||
include "mlir/IR/OpBase.td"
|
||||
include "mlir/IR/AttrTypeBase.td"
|
||||
|
||||
// All of the types will extend this class.
|
||||
class Serene_Type<string name> : TypeDef<Serene_Dialect, name> { }
|
||||
// The base class for all the Serene types
|
||||
class Serene_Type<string name, string typeMnemonic, list<Trait> traits = []>
|
||||
: TypeDef<Serene_Dialect, name, traits> {
|
||||
let mnemonic = typeMnemonic;
|
||||
}
|
||||
|
||||
// The base class for all the Serene attributes
|
||||
class Serene_Attr<string name, string attrMnemonic, list<Trait> traits = []>
|
||||
: AttrDef<Serene_Dialect, name, traits> {
|
||||
let mnemonic = attrMnemonic;
|
||||
}
|
||||
|
||||
// Attributes =================================================================
|
||||
def SymbolAttr : Serene_Attr<"Symbol", "symbol"> {
|
||||
let summary = "An Attribute containing a symbol value.";
|
||||
let description = [{
|
||||
An integer attribute is a literal attribute that represents a symbol
|
||||
value.
|
||||
}];
|
||||
|
||||
let parameters = (ins StringRefParameter<"The namespace of the symbol">:$ns,
|
||||
StringRefParameter<"The symbol name itself">:$name);
|
||||
|
||||
let assemblyFormat = "`<` $ns `,` $name `>`";
|
||||
}
|
||||
|
||||
// Type Traits ================================================================
|
||||
def AnyPtr : Type<CPred<"$_self.isa<PtrType>()">,
|
||||
"Serene pointer type", "Ptr">;
|
||||
|
||||
|
@ -44,8 +69,8 @@ class Ptr<Type type> : Type<
|
|||
}
|
||||
|
||||
|
||||
def PtrType : Serene_Type<"Ptr"> {
|
||||
let mnemonic = "ptr";
|
||||
// Types ======================================================================
|
||||
def PtrType : Serene_Type<"Ptr", "ptr"> {
|
||||
let summary = "A pointer to a value of type T.";
|
||||
|
||||
let description = [{
|
||||
|
@ -70,8 +95,7 @@ def PtrType : Serene_Type<"Ptr"> {
|
|||
}];
|
||||
}
|
||||
|
||||
def StringType : Serene_Type<"String"> {
|
||||
let mnemonic = "string";
|
||||
def StringType : Serene_Type<"String", "string"> {
|
||||
let summary = "A simple string type";
|
||||
|
||||
let description = [{
|
||||
|
@ -83,9 +107,7 @@ def StringType : Serene_Type<"String"> {
|
|||
}
|
||||
|
||||
|
||||
def SymbolType : Serene_Type<"Symbol"> {
|
||||
let mnemonic = "symbol";
|
||||
|
||||
def SymbolType : Serene_Type<"Symbol", "symbol"> {
|
||||
let summary = "A Lisp symbol type";
|
||||
|
||||
let description = [{
|
||||
|
@ -94,8 +116,7 @@ def SymbolType : Serene_Type<"Symbol"> {
|
|||
// let parameters = (ins "std::string":$ns, "std::string":$name);
|
||||
}
|
||||
|
||||
def FnType : Serene_Type<"Fn"> {
|
||||
let mnemonic = "fn";
|
||||
def FnType : Serene_Type<"Fn", "fn"> {
|
||||
|
||||
let summary = "Function type";
|
||||
|
||||
|
@ -116,4 +137,5 @@ def Serene_Type : AnyTypeOf<[
|
|||
FnType
|
||||
]>;
|
||||
|
||||
|
||||
#endif // SERENE_DIALECT_TYPES_TD
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <serene/config.h>
|
||||
|
||||
#include <llvm/Support/Casting.h>
|
||||
#include <llvm/Support/Error.h>
|
||||
#include <llvm/Support/ErrorHandling.h>
|
||||
#include <llvm/Support/raw_ostream.h>
|
||||
#include <llvm/Support/thread.h>
|
||||
|
@ -54,202 +55,318 @@ namespace ll = mlir::LLVM;
|
|||
|
||||
namespace serene::passes {
|
||||
|
||||
static ll::GlobalOp getOrCreateInternalString(mlir::Location loc,
|
||||
mlir::OpBuilder &builder,
|
||||
llvm::StringRef name,
|
||||
llvm::StringRef value,
|
||||
mlir::ModuleOp module) {
|
||||
// static ll::GlobalOp getOrCreateInternalString(mlir::Location loc,
|
||||
// mlir::OpBuilder &builder,
|
||||
// llvm::StringRef name,
|
||||
// llvm::StringRef value,
|
||||
// mlir::ModuleOp module) {
|
||||
|
||||
// Create the global at the entry of the module.
|
||||
ll::GlobalOp global;
|
||||
// // Create the global at the entry of the module.
|
||||
// ll::GlobalOp global;
|
||||
|
||||
if (!(global = module.lookupSymbol<ll::GlobalOp>(name))) {
|
||||
mlir::OpBuilder::InsertionGuard insertGuard(builder);
|
||||
builder.setInsertionPointToStart(module.getBody());
|
||||
// if (!(global = module.lookupSymbol<ll::GlobalOp>(name))) {
|
||||
// mlir::OpBuilder::InsertionGuard insertGuard(builder);
|
||||
// builder.setInsertionPointToStart(module.getBody());
|
||||
|
||||
auto type = ll::LLVMArrayType::get(
|
||||
mlir::IntegerType::get(builder.getContext(), I8_SIZE), value.size());
|
||||
// TODO: Do we want link once ?
|
||||
global = builder.create<ll::GlobalOp>(loc, type, /*isConstant=*/true,
|
||||
ll::Linkage::Linkonce, name,
|
||||
builder.getStringAttr(value),
|
||||
/*alignment=*/0);
|
||||
}
|
||||
// auto type = ll::LLVMArrayType::get(
|
||||
// mlir::IntegerType::get(builder.getContext(), I8_SIZE), value.size());
|
||||
// // TODO: Do we want link once ?
|
||||
// global = builder.create<ll::GlobalOp>(loc, type, /*isConstant=*/true,
|
||||
// ll::Linkage::Linkonce, name,
|
||||
// builder.getStringAttr(value),
|
||||
// /*alignment=*/0);
|
||||
// }
|
||||
|
||||
return global;
|
||||
};
|
||||
// return global;
|
||||
// };
|
||||
|
||||
static mlir::Value getPtrToInternalString(mlir::OpBuilder &builder,
|
||||
ll::GlobalOp global) {
|
||||
auto loc = global.getLoc();
|
||||
auto I8 = mlir::IntegerType::get(builder.getContext(), I8_SIZE);
|
||||
// Get the pointer to the first character in the global string.
|
||||
mlir::Value globalPtr = builder.create<ll::AddressOfOp>(loc, global);
|
||||
mlir::Value cst0 = builder.create<ll::ConstantOp>(
|
||||
loc, mlir::IntegerType::get(builder.getContext(), I64_SIZE),
|
||||
builder.getIntegerAttr(builder.getIndexType(), 0));
|
||||
// static mlir::Value getPtrToInternalString(mlir::OpBuilder &builder,
|
||||
// ll::GlobalOp global) {
|
||||
// auto loc = global.getLoc();
|
||||
// auto I8 = mlir::IntegerType::get(builder.getContext(), I8_SIZE);
|
||||
// // Get the pointer to the first character in the global string.
|
||||
// mlir::Value globalPtr = builder.create<ll::AddressOfOp>(loc, global);
|
||||
// mlir::Value cst0 = builder.create<ll::ConstantOp>(
|
||||
// loc, mlir::IntegerType::get(builder.getContext(), I64_SIZE),
|
||||
// builder.getIntegerAttr(builder.getIndexType(), 0));
|
||||
|
||||
return builder.create<ll::GEPOp>(loc, ll::LLVMPointerType::get(I8), globalPtr,
|
||||
llvm::ArrayRef<mlir::Value>({cst0}));
|
||||
};
|
||||
// return builder.create<ll::GEPOp>(loc, ll::LLVMPointerType::get(I8),
|
||||
// globalPtr,
|
||||
// llvm::ArrayRef<mlir::Value>({cst0}));
|
||||
// };
|
||||
|
||||
static ll::GlobalOp getOrCreateString(mlir::Location loc,
|
||||
mlir::OpBuilder &builder,
|
||||
llvm::StringRef name,
|
||||
llvm::StringRef value, uint32_t len,
|
||||
mlir::ModuleOp module) {
|
||||
auto *ctx = builder.getContext();
|
||||
ll::GlobalOp global;
|
||||
// static ll::GlobalOp getOrCreateString(mlir::Location loc,
|
||||
// mlir::OpBuilder &builder,
|
||||
// llvm::StringRef name,
|
||||
// llvm::StringRef value, uint32_t len,
|
||||
// mlir::ModuleOp module) {
|
||||
// auto *ctx = builder.getContext();
|
||||
// ll::GlobalOp global;
|
||||
|
||||
if (!(global = module.lookupSymbol<ll::GlobalOp>(name))) {
|
||||
// if (!(global = module.lookupSymbol<ll::GlobalOp>(name))) {
|
||||
|
||||
mlir::OpBuilder::InsertionGuard insertGuard(builder);
|
||||
builder.setInsertionPointToStart(module.getBody());
|
||||
// mlir::OpBuilder::InsertionGuard insertGuard(builder);
|
||||
// builder.setInsertionPointToStart(module.getBody());
|
||||
|
||||
mlir::Attribute initValue{};
|
||||
auto type = slir::getStringTypeinLLVM(*ctx);
|
||||
// mlir::Attribute initValue{};
|
||||
// auto type = slir::getStringTypeinLLVM(*ctx);
|
||||
|
||||
global = builder.create<ll::GlobalOp>(
|
||||
loc, type, /*isConstant=*/true, ll::Linkage::Linkonce, name, initValue);
|
||||
// global = builder.create<ll::GlobalOp>(
|
||||
// loc, type, /*isConstant=*/true, ll::Linkage::Linkonce, name,
|
||||
// initValue);
|
||||
|
||||
auto &gr = global.getInitializerRegion();
|
||||
auto *block = builder.createBlock(&gr);
|
||||
// auto &gr = global.getInitializerRegion();
|
||||
// auto *block = builder.createBlock(&gr);
|
||||
|
||||
if (block == nullptr) {
|
||||
module.emitError("Faild to create block of the globalOp!");
|
||||
// TODO: change the return type to Expected<GlobalOp> and return
|
||||
// an error here
|
||||
}
|
||||
// if (block == nullptr) {
|
||||
// module.emitError("Faild to create block of the globalOp!");
|
||||
// // TODO: change the return type to Expected<GlobalOp> and return
|
||||
// // an error here
|
||||
// }
|
||||
|
||||
builder.setInsertionPoint(block, block->begin());
|
||||
// builder.setInsertionPoint(block, block->begin());
|
||||
|
||||
mlir::Value structInstant = builder.create<ll::UndefOp>(loc, type);
|
||||
// mlir::Value structInstant = builder.create<ll::UndefOp>(loc, type);
|
||||
|
||||
auto strOp = getOrCreateInternalString(loc, builder, name, value, module);
|
||||
auto ptrToStr = getPtrToInternalString(builder, strOp);
|
||||
// auto strOp = getOrCreateInternalString(loc, builder, name, value,
|
||||
// module); auto ptrToStr = getPtrToInternalString(builder, strOp);
|
||||
|
||||
auto length = builder.create<ll::ConstantOp>(
|
||||
loc, mlir::IntegerType::get(ctx, I32_SIZE),
|
||||
builder.getI32IntegerAttr(len));
|
||||
// auto length = builder.create<ll::ConstantOp>(
|
||||
// loc, mlir::IntegerType::get(ctx, I32_SIZE),
|
||||
// builder.getI32IntegerAttr(len));
|
||||
|
||||
// Setting the string pointer field
|
||||
structInstant = builder.create<ll::InsertValueOp>(
|
||||
loc, structInstant.getType(), structInstant, ptrToStr,
|
||||
builder.getI64ArrayAttr(0));
|
||||
// // Setting the string pointer field
|
||||
// structInstant = builder.create<ll::InsertValueOp>(
|
||||
// loc, structInstant.getType(), structInstant, ptrToStr,
|
||||
// builder.getI64ArrayAttr(0));
|
||||
|
||||
// Setting the len field
|
||||
structInstant = builder.create<ll::InsertValueOp>(
|
||||
loc, structInstant.getType(), structInstant, length,
|
||||
builder.getI64ArrayAttr(1));
|
||||
// // Setting the len field
|
||||
// structInstant = builder.create<ll::InsertValueOp>(
|
||||
// loc, structInstant.getType(), structInstant, length,
|
||||
// builder.getI64ArrayAttr(1));
|
||||
|
||||
builder.create<ll::ReturnOp>(loc, structInstant);
|
||||
}
|
||||
// builder.create<ll::ReturnOp>(loc, structInstant);
|
||||
// }
|
||||
|
||||
return global;
|
||||
};
|
||||
// return global;
|
||||
// };
|
||||
|
||||
static ll::GlobalOp getOrCreateSymbol(mlir::Location loc,
|
||||
mlir::OpBuilder &builder,
|
||||
llvm::StringRef ns, llvm::StringRef name,
|
||||
mlir::ModuleOp module) {
|
||||
std::string fqName;
|
||||
ll::GlobalOp global;
|
||||
// static ll::GlobalOp getOrCreateSymbol(mlir::Location loc,
|
||||
// mlir::OpBuilder &builder,
|
||||
// llvm::StringRef ns, llvm::StringRef
|
||||
// name, mlir::ModuleOp module) {
|
||||
// std::string fqName;
|
||||
// ll::GlobalOp global;
|
||||
|
||||
auto *ctx = builder.getContext();
|
||||
auto symName = serene::mangleInternalSymName(fqName);
|
||||
// auto *ctx = builder.getContext();
|
||||
// auto symName = serene::mangleInternalSymName(fqName);
|
||||
|
||||
makeFQSymbolName(ns, name, fqName);
|
||||
// makeFQSymbolName(ns, name, fqName);
|
||||
|
||||
if (!(global = module.lookupSymbol<ll::GlobalOp>(symName))) {
|
||||
mlir::OpBuilder::InsertionGuard insertGuard(builder);
|
||||
builder.setInsertionPointToStart(module.getBody());
|
||||
// if (!(global = module.lookupSymbol<ll::GlobalOp>(symName))) {
|
||||
// mlir::OpBuilder::InsertionGuard insertGuard(builder);
|
||||
// builder.setInsertionPointToStart(module.getBody());
|
||||
|
||||
mlir::Attribute initValue{};
|
||||
auto type = slir::getSymbolTypeinLLVM(*ctx);
|
||||
// mlir::Attribute initValue{};
|
||||
// auto type = slir::getSymbolTypeinLLVM(*ctx);
|
||||
|
||||
// We want to allow merging the strings representing the ns or name part
|
||||
// of the symbol with other modules to unify them.
|
||||
ll::Linkage linkage = ll::Linkage::Linkonce;
|
||||
// // We want to allow merging the strings representing the ns or name part
|
||||
// // of the symbol with other modules to unify them.
|
||||
// ll::Linkage linkage = ll::Linkage::Linkonce;
|
||||
|
||||
global = builder.create<ll::GlobalOp>(loc, type, /*isConstant=*/true,
|
||||
linkage, symName, initValue);
|
||||
// global = builder.create<ll::GlobalOp>(loc, type, /*isConstant=*/true,
|
||||
// linkage, symName, initValue);
|
||||
|
||||
auto &gr = global.getInitializerRegion();
|
||||
auto *block = builder.createBlock(&gr);
|
||||
// auto &gr = global.getInitializerRegion();
|
||||
// auto *block = builder.createBlock(&gr);
|
||||
|
||||
if (block == nullptr) {
|
||||
module.emitError("Faild to create block of the globalOp!");
|
||||
// TODO: change the return type to Expected<GlobalOp> and return
|
||||
// an error here
|
||||
}
|
||||
// if (block == nullptr) {
|
||||
// module.emitError("Faild to create block of the globalOp!");
|
||||
// // TODO: change the return type to Expected<GlobalOp> and return
|
||||
// // an error here
|
||||
// }
|
||||
|
||||
builder.setInsertionPoint(block, block->begin());
|
||||
// builder.setInsertionPoint(block, block->begin());
|
||||
|
||||
mlir::Value structInstant = builder.create<ll::UndefOp>(loc, type);
|
||||
// mlir::Value structInstant = builder.create<ll::UndefOp>(loc, type);
|
||||
|
||||
// We want to use the mangled ns as the name of the constant that
|
||||
// holds the ns string
|
||||
auto mangledNSName = serene::mangleInternalStringName(ns);
|
||||
// The globalop that we want to use for the ns field
|
||||
auto nsField =
|
||||
getOrCreateString(loc, builder, mangledNSName, ns, ns.size(), module);
|
||||
auto ptrToNs = builder.create<ll::AddressOfOp>(loc, nsField);
|
||||
// // We want to use the mangled ns as the name of the constant that
|
||||
// // holds the ns string
|
||||
// auto mangledNSName = serene::mangleInternalStringName(ns);
|
||||
// // The globalop that we want to use for the ns field
|
||||
// auto nsField =
|
||||
// getOrCreateString(loc, builder, mangledNSName, ns, ns.size(),
|
||||
// module);
|
||||
// auto ptrToNs = builder.create<ll::AddressOfOp>(loc, nsField);
|
||||
|
||||
// We want to use the mangled 'name' as the name of the constant that
|
||||
// holds the 'name' string
|
||||
auto mangledName = serene::mangleInternalStringName(name);
|
||||
// The global op to use as the 'name' field
|
||||
auto nameField =
|
||||
getOrCreateString(loc, builder, mangledName, name, name.size(), module);
|
||||
auto ptrToName = builder.create<ll::AddressOfOp>(loc, nameField);
|
||||
// // We want to use the mangled 'name' as the name of the constant that
|
||||
// // holds the 'name' string
|
||||
// auto mangledName = serene::mangleInternalStringName(name);
|
||||
// // The global op to use as the 'name' field
|
||||
// auto nameField =
|
||||
// getOrCreateString(loc, builder, mangledName, name, name.size(),
|
||||
// module);
|
||||
// auto ptrToName = builder.create<ll::AddressOfOp>(loc, nameField);
|
||||
|
||||
// Setting the string pointer field
|
||||
structInstant = builder.create<ll::InsertValueOp>(
|
||||
loc, structInstant.getType(), structInstant, ptrToNs,
|
||||
builder.getI64ArrayAttr(0));
|
||||
// // Setting the string pointer field
|
||||
// structInstant = builder.create<ll::InsertValueOp>(
|
||||
// loc, structInstant.getType(), structInstant, ptrToNs,
|
||||
// builder.getI64ArrayAttr(0));
|
||||
|
||||
// Setting the len field
|
||||
structInstant = builder.create<ll::InsertValueOp>(
|
||||
loc, structInstant.getType(), structInstant, ptrToName,
|
||||
builder.getI64ArrayAttr(0));
|
||||
// // Setting the len field
|
||||
// structInstant = builder.create<ll::InsertValueOp>(
|
||||
// loc, structInstant.getType(), structInstant, ptrToName,
|
||||
// builder.getI64ArrayAttr(0));
|
||||
|
||||
builder.create<ll::ReturnOp>(loc, structInstant);
|
||||
}
|
||||
// builder.create<ll::ReturnOp>(loc, structInstant);
|
||||
// }
|
||||
|
||||
return global;
|
||||
};
|
||||
// return global;
|
||||
// };
|
||||
|
||||
struct LowerSymbol : public mlir::OpConversionPattern<slir::SymbolOp> {
|
||||
using OpConversionPattern<slir::SymbolOp>::OpConversionPattern;
|
||||
// static ll::GlobalOp getOrCreateSymbol(mlir::Location loc,
|
||||
// mlir::OpBuilder &builder, mlir::Value
|
||||
// ns, mlir::Value name, mlir::ModuleOp
|
||||
// module) {
|
||||
|
||||
mlir::LogicalResult
|
||||
matchAndRewrite(serene::slir::SymbolOp op, OpAdaptor adaptor,
|
||||
mlir::ConversionPatternRewriter &rewriter) const override;
|
||||
};
|
||||
// assert(!ns.getType().isa<slir::StringType>() &&
|
||||
// !ns.getType().isa<slir::StringType>() &&
|
||||
// "TypeError: ns and name has to be strings");
|
||||
|
||||
mlir::LogicalResult
|
||||
LowerSymbol::matchAndRewrite(serene::slir::SymbolOp op, OpAdaptor adaptor,
|
||||
mlir::ConversionPatternRewriter &rewriter) const {
|
||||
// std::string fqName;
|
||||
// ll::GlobalOp global;
|
||||
|
||||
UNUSED(adaptor);
|
||||
auto ns = op.ns();
|
||||
auto name = op.name();
|
||||
auto loc = op.getLoc();
|
||||
auto module = op->getParentOfType<mlir::ModuleOp>();
|
||||
// auto *ctx = builder.getContext();
|
||||
// auto symName = serene::mangleInternalSymName(fqName);
|
||||
|
||||
// If there is no use for the result of this op then simply erase it
|
||||
if (op.getResult().use_empty()) {
|
||||
rewriter.eraseOp(op);
|
||||
return mlir::success();
|
||||
}
|
||||
// makeFQSymbolName(ns, name, fqName);
|
||||
|
||||
auto global = getOrCreateSymbol(loc, rewriter, ns, name, module);
|
||||
auto ptr = rewriter.create<ll::AddressOfOp>(loc, global);
|
||||
// if (!(global = module.lookupSymbol<ll::GlobalOp>(symName))) {
|
||||
// mlir::OpBuilder::InsertionGuard insertGuard(builder);
|
||||
// builder.setInsertionPointToStart(module.getBody());
|
||||
|
||||
rewriter.replaceOp(op, ptr.getResult());
|
||||
// mlir::Attribute initValue{};
|
||||
// auto type = slir::getSymbolTypeinLLVM(*ctx);
|
||||
|
||||
return mlir::success();
|
||||
}
|
||||
// // We want to allow merging the strings representing the ns or name part
|
||||
// // of the symbol with other modules to unify them.
|
||||
// ll::Linkage linkage = ll::Linkage::Linkonce;
|
||||
|
||||
// global = builder.create<ll::GlobalOp>(loc, type, /*isConstant=*/true,
|
||||
// linkage, symName, initValue);
|
||||
|
||||
// auto &gr = global.getInitializerRegion();
|
||||
// auto *block = builder.createBlock(&gr);
|
||||
|
||||
// if (block == nullptr) {
|
||||
// module.emitError("Faild to create block of the globalOp!");
|
||||
// // TODO: change the return type to Expected<GlobalOp> and return
|
||||
// // an error here
|
||||
// }
|
||||
|
||||
// builder.setInsertionPoint(block, block->begin());
|
||||
|
||||
// mlir::Value structInstant = builder.create<ll::UndefOp>(loc, type);
|
||||
|
||||
// // We want to use the mangled ns as the name of the constant that
|
||||
// // holds the ns string
|
||||
// auto mangledNSName = serene::mangleInternalStringName(ns);
|
||||
// // The globalop that we want to use for the ns field
|
||||
// auto nsField =
|
||||
// getOrCreateString(loc, builder, mangledNSName, ns, ns.size(),
|
||||
// module);
|
||||
// auto ptrToNs = builder.create<ll::AddressOfOp>(loc, nsField);
|
||||
|
||||
// // We want to use the mangled 'name' as the name of the constant that
|
||||
// // holds the 'name' string
|
||||
// auto mangledName = serene::mangleInternalStringName(name);
|
||||
// // The global op to use as the 'name' field
|
||||
// auto nameField =
|
||||
// getOrCreateString(loc, builder, mangledName, name, name.size(),
|
||||
// module);
|
||||
// auto ptrToName = builder.create<ll::AddressOfOp>(loc, nameField);
|
||||
|
||||
// // Setting the string pointer field
|
||||
// structInstant = builder.create<ll::InsertValueOp>(
|
||||
// loc, structInstant.getType(), structInstant, ptrToNs,
|
||||
// builder.getI64ArrayAttr(0));
|
||||
|
||||
// // Setting the len field
|
||||
// structInstant = builder.create<ll::InsertValueOp>(
|
||||
// loc, structInstant.getType(), structInstant, ptrToName,
|
||||
// builder.getI64ArrayAttr(0));
|
||||
|
||||
// builder.create<ll::ReturnOp>(loc, structInstant);
|
||||
// }
|
||||
|
||||
// return global;
|
||||
// };
|
||||
|
||||
// struct LowerIntern : public mlir::OpConversionPattern<slir::InternOp> {
|
||||
// using OpConversionPattern<slir::InternOp>::OpConversionPattern;
|
||||
|
||||
// mlir::LogicalResult
|
||||
// matchAndRewrite(serene::slir::InternOp op, OpAdaptor adaptor,
|
||||
// mlir::ConversionPatternRewriter &rewriter) const override;
|
||||
// };
|
||||
|
||||
// mlir::LogicalResult
|
||||
// LowerIntern::matchAndRewrite(serene::slir::InternOp op, OpAdaptor adaptor,
|
||||
// mlir::ConversionPatternRewriter &rewriter) const
|
||||
// {
|
||||
|
||||
// UNUSED(adaptor);
|
||||
// auto ns = op.ns();
|
||||
// auto name = op.name();
|
||||
// auto loc = op.getLoc();
|
||||
// auto module = op->getParentOfType<mlir::ModuleOp>();
|
||||
|
||||
// // If there is no use for the result of this op then simply erase it
|
||||
// if (op.getResult().use_empty()) {
|
||||
// rewriter.eraseOp(op);
|
||||
// return mlir::success();
|
||||
// }
|
||||
|
||||
// auto global = getOrCreateSymbol(loc, rewriter, ns, name, module);
|
||||
// auto ptr = rewriter.create<ll::AddressOfOp>(loc, global);
|
||||
|
||||
// rewriter.replaceOp(op, ptr.getResult());
|
||||
|
||||
// return mlir::success();
|
||||
// }
|
||||
|
||||
// struct LowerSymbol : public mlir::OpConversionPattern<slir::SymbolOp> {
|
||||
// using OpConversionPattern<slir::SymbolOp>::OpConversionPattern;
|
||||
|
||||
// mlir::LogicalResult
|
||||
// matchAndRewrite(serene::slir::SymbolOp op, OpAdaptor adaptor,
|
||||
// mlir::ConversionPatternRewriter &rewriter) const override;
|
||||
// };
|
||||
|
||||
// mlir::LogicalResult
|
||||
// LowerSymbol::matchAndRewrite(serene::slir::SymbolOp op, OpAdaptor adaptor,
|
||||
// mlir::ConversionPatternRewriter &rewriter) const
|
||||
// {
|
||||
|
||||
// UNUSED(adaptor);
|
||||
// auto ns = op.ns();
|
||||
// auto name = op.name();
|
||||
// auto loc = op.getLoc();
|
||||
// auto module = op->getParentOfType<mlir::ModuleOp>();
|
||||
|
||||
// // If there is no use for the result of this op then simply erase it
|
||||
// if (op.getResult().use_empty()) {
|
||||
// rewriter.eraseOp(op);
|
||||
// return mlir::success();
|
||||
// }
|
||||
|
||||
// auto global = getOrCreateSymbol(loc, rewriter, ns, name, module);
|
||||
// auto ptr = rewriter.create<ll::AddressOfOp>(loc, global);
|
||||
|
||||
// rewriter.replaceOp(op, ptr.getResult());
|
||||
|
||||
// return mlir::success();
|
||||
// }
|
||||
|
||||
struct LowerDefine : public mlir::OpConversionPattern<slir::DefineOp> {
|
||||
using OpConversionPattern<slir::DefineOp>::OpConversionPattern;
|
||||
|
@ -464,8 +581,8 @@ class LowerSLIR : public LowerSLIRBase<LowerSLIR> {
|
|||
|
||||
// Pattern to lower ValueOp and FnOp
|
||||
// LowerDefineConstant
|
||||
patterns.add<LowerSymbol, LowerDefine, LowerDefineConstant>(typeConverter,
|
||||
&getContext());
|
||||
patterns.add<LowerDefine, LowerDefineConstant>(typeConverter,
|
||||
&getContext());
|
||||
|
||||
// With the target and rewrite patterns defined, we can now attempt the
|
||||
// conversion. The conversion will signal failure if any of our `illegal`
|
||||
|
|
|
@ -45,6 +45,11 @@ mlir::DataLayoutSpecInterface NsOp::getDataLayoutSpec() {
|
|||
return {};
|
||||
}
|
||||
|
||||
mlir::OpFoldResult SymbolOp::fold(llvm::ArrayRef<mlir::Attribute> operands) {
|
||||
UNUSED(operands);
|
||||
return value();
|
||||
};
|
||||
|
||||
mlir::OpFoldResult ValueOp::fold(llvm::ArrayRef<mlir::Attribute> operands) {
|
||||
UNUSED(operands);
|
||||
return value();
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
|
||||
#include "serene/slir/dialect.h"
|
||||
|
||||
#define GET_ATTRDEF_CLASSES
|
||||
#include "serene/slir/attrs.c.inc"
|
||||
|
||||
#define GET_TYPEDEF_CLASSES
|
||||
#include "serene/slir/types.cpp.inc"
|
||||
|
||||
|
@ -36,6 +39,10 @@ PtrType PtrType::get(mlir::Type pointee, unsigned addressSpace) {
|
|||
bool PtrType::isOpaque() const { return !getImpl()->pointeeType; }
|
||||
|
||||
void SereneDialect::registerType() {
|
||||
addAttributes<
|
||||
#define GET_ATTRDEF_LIST
|
||||
#include "serene/slir/attrs.cpp.inc"
|
||||
>();
|
||||
addTypes<
|
||||
#define GET_TYPEDEF_LIST
|
||||
#include "serene/slir/types.cpp.inc"
|
||||
|
|
Loading…
Reference in New Issue