Fix the slir fn operator and introduce return

This commit is contained in:
Sameer Rahmani 2021-09-19 21:56:00 +01:00
parent f980da8e4e
commit e69ee4dc8f
5 changed files with 75 additions and 38 deletions

View File

@ -170,7 +170,8 @@ CLOSED: [2021-09-04 Sat 10:53]
*** The owner of LLVM/MLIR contexts
*** Holds the namespace table
*** Probably will contain the primitive types as well
* Episode 8 - MLIR Basics
* DONE Episode 8 - MLIR Basics
CLOSED: [2021-09-17 Fri 10:18]
** Serene Changes
- Introducing a SourceManager
- Reader changes
@ -375,3 +376,23 @@ define i64 @main1(i64 %0, i64 %1, i64 %2) !dbg !9 {
- https://mlir.llvm.org/docs
- https://mlir.llvm.org/docs/LangRef
- https://en.wikipedia.org/wiki/Basic_block
* Episode 9 - Code Generation
** Updates:
There will be an episode dedicated to eache of these
- Source manager
- Diagnostic Engine
- JIT
** How to define a new dialect
- Pure C++
- Tablegen
** SLIR
*** The SLIR goal
- An IR that follows the AST
- Rename?
*** Steps
- [ ] Define the new dialect
- [ ] Setup the tablegen
- [ ] Define the operations
- [ ] Walk the AST and generate the operations

View File

@ -27,6 +27,7 @@
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/Dialect.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "mlir/Interfaces/ControlFlowInterfaces.h"
// Include the auto-generated header file containing the declaration of the
// serene's dialect.

View File

@ -2,10 +2,15 @@
#define SERENE_DIALECT
include "mlir/IR/OpBase.td"
include "mlir/IR/OpAsmInterface.td"
include "mlir/IR/SymbolInterfaces.td"
include "mlir/Interfaces/SideEffectInterfaces.td"
include "mlir/Interfaces/CallInterfaces.td"
include "mlir/Interfaces/CastInterfaces.td"
include "mlir/Interfaces/SideEffectInterfaces.td"
include "mlir/Interfaces/ControlFlowInterfaces.td"
include "mlir/Interfaces/DataLayoutInterfaces.td"
include "mlir/Interfaces/VectorInterfaces.td"
// Dialect definition. It will directly generate the SereneDialect class
@ -32,43 +37,11 @@ class Serene_Op<string mnemonic, list<OpTrait> traits = []> :
class Serene_Type<string name> : TypeDef<Serene_Dialect, name> { }
// def SymbolType : Serene_Type<"Symbol"> {
// let mnemonic = "symbol";
// let summary = "A typical Lisp symbol";
// let description = [{
// A symbol is just a name and nothing more. Just a name
// to give to a value or to use it as it is.
// }];
// // let cppNamespace = "::serene::sir";
// let parameters = (ins "std::string":$name);
// // We define the printer inline.
// let printer = [{
// $_printer << "Symbol<" << getImpl()->name << ">";
// }];
// // The parser is defined here also.
// let parser = [{
// if ($_parser.parseLess())
// return Type();
// std::string name;
// if ($_parser.parseInteger(name))
// return Type();
// return get($_ctxt, name);
// }];
// }
def ValueOp: Serene_Op<"value"> {
let summary = "This operation represent a value";
let description = [{
some description
ValueOp
}];
let arguments = (ins I64Attr:$value);
@ -85,9 +58,12 @@ def ValueOp: Serene_Op<"value"> {
];
}
// TODO: Add the FunctionLike trait here and include its header file in dialect.h
def FnOp: Serene_Op<"fn", [
AffineScope, AutomaticAllocationScope,
IsolatedFromAbove
IsolatedFromAbove,
]> {
let summary = "This operation is just a place holder for a function";
@ -102,7 +78,7 @@ def FnOp: Serene_Op<"fn", [
OptionalAttr<StrAttr>:$sym_visibility);
let regions = (region AnyRegion:$body);
let results = (outs NoneType);
let results = (outs I64);
// let builders = [
// OpBuilder<(ins
@ -121,4 +97,30 @@ def FnOp: Serene_Op<"fn", [
// llvm::ArrayRef<mlir::DictionaryAttr> argAttrs);
// }];
}
def ReturnOp: Serene_Op<"return", [NoSideEffect, HasParent<"FnOp">,
ReturnLike, Terminator]> {
let summary = "This operation marks the return value of a function";
let description = [{
ReturnOp
}];
let arguments = (ins AnyType:$operand);
// let verifier = [{ return serene::sir::verify(*this); }];
// let builders = [
// OpBuilder<(ins "int":$value), [{
// // Build from fix 64 bit int
// build(odsBuilder, odsState, odsBuilder.getI64Type(), (uint64_t) value);
// }]>,
// ];
}
#endif // SERENE_DIALECT

View File

@ -133,23 +133,29 @@ void Fn::generateIR(serene::Namespace &ns, mlir::ModuleOp &m) {
mlir::DictionaryAttr::get(builder.getContext(), arguments),
builder.getStringAttr("public"));
if (!fn) {
m.emitError(llvm::formatv("Can't create the function '{0}'", name));
return;
}
auto *entryBlock = new mlir::Block();
auto &body = fn.body();
auto *entryBlock = new mlir::Block();
body.push_back(entryBlock);
builder.setInsertionPointToStart(entryBlock);
auto retVal = builder.create<slir::ValueOp>(loc, 0).getResult();
mlir::ReturnOp returnOp = builder.create<mlir::ReturnOp>(loc, retVal);
slir::ReturnOp returnOp = builder.create<slir::ReturnOp>(loc, retVal);
if (!returnOp) {
m.emitError(
llvm::formatv("Can't create the return value of function '{0}'", name));
fn.erase();
return;
}
m.push_back(fn);
};
} // namespace exprs

View File

@ -30,6 +30,7 @@
#include "serene/llvm/IR/Value.h"
#include "serene/slir/slir.h"
#include <mlir/IR/Verifier.h>
#include <llvm/ADT/StringRef.h>
#include <llvm/Support/FormatVariadic.h>
#include <llvm/Support/raw_ostream.h>
@ -81,6 +82,12 @@ MaybeModuleOp Namespace::generate() {
x->generateIR(*this, module);
}
if(mlir::failed(mlir::verify(module))) {
module.emitError("Can't verify the module");
module.erase();
return MaybeModuleOp::error(true);
}
if (mlir::failed(runPasses(module))) {
// TODO: throw a proper errer
module.emitError("Failure in passes!");