Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frontend refactor #425

Merged
merged 17 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 85 additions & 47 deletions include/vast/CodeGen/CodeGen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,16 @@ namespace vast::cg
} // namespace detail

//
// CodeGenUnit
// codegen_base
//
// It takes care of translation of single translation unit or declaration.
//
template< typename CGVisitor, typename CGContext >
struct CodeGenBase
template< typename visitor_t, typename context_t >
struct codegen_base
{
using MetaGenerator = typename CGVisitor::MetaGeneratorType;
using meta_generator = typename visitor_t::meta_generator;

using code_gen_context = CGContext;

CodeGenBase(CGContext &cgctx, MetaGenerator &meta)
codegen_base(context_t &cgctx, meta_generator &meta)
: _mctx(&cgctx.mctx)
, _meta(meta)
, _cgctx(cgctx)
Expand Down Expand Up @@ -94,7 +92,7 @@ namespace vast::cg
using FunctionsScope = ScopedSymbolTable< mangled_name_ref, hl::FuncOp >;
using VariablesScope = ScopedSymbolTable< const clang::VarDecl *, Value >;

struct CodegenScope {
struct cg_scope {
TypeDefsScope typedefs;
TypeDeclsScope typedecls;
EnumDeclsScope enumdecls;
Expand Down Expand Up @@ -170,7 +168,7 @@ namespace vast::cg
VAST_UNIMPLEMENTED;
}

typename CGContext::VarTable& variables_symbol_table() { return _cgctx.vars; }
typename context_t::var_table& variables_symbol_table() { return _cgctx.vars; }

// correspond to clang::CodeGenFunction::GenerateCode
hl::FuncOp emit_function_prologue(
Expand Down Expand Up @@ -303,20 +301,51 @@ namespace vast::cg
return fn;
}

template< typename... Args >
mlir_value constant(Args &&...args) {
return _visitor->constant(std::forward< Args >(args)...);
}

template< typename Op, typename... Args >
auto make(Args &&...args) {
return _visitor->template create< Op >(std::forward< Args >(args)...);
}

auto insert_at_end(hl::FuncOp fn) {
auto guard = _visitor->make_insertion_guard();
_visitor->set_insertion_point_to_end(&fn.getBody());
return std::move(guard);
}

void emit_implicit_return_zero(hl::FuncOp fn, const clang::FunctionDecl *decl) {
auto guard = insert_at_end(fn);
auto loc = meta_location(decl);

auto fty = fn.getFunctionType();
auto zero = _visitor->constant(loc, fty.getResult(0), apsint(0));
make< core::ImplicitReturnOp >(loc, zero);
}

void emit_implicit_void_return(hl::FuncOp fn, const clang::FunctionDecl *decl) {
VAST_CHECK(
decl->getReturnType()->isVoidType(),
VAST_CHECK( decl->getReturnType()->isVoidType(),
"Can't emit implicit void return in non-void function."
);
auto &builder = _visitor->base_builder();
auto g = _visitor->make_insertion_guard();
_visitor->set_insertion_point_to_end(&fn.getBody());

auto loc = meta_location(decl);
auto void_type = _visitor->Visit(decl->getReturnType());
auto void_const =
builder.template create< hl::ConstantOp >(loc, cast< hl::VoidType >(void_type));
builder.template create< core::ImplicitReturnOp >(loc, void_const.getResult());
auto guard = insert_at_end(fn);

auto loc = meta_location(decl);
make< core::ImplicitReturnOp >(loc, constant(loc));
}

void emit_trap(hl::FuncOp fn, const clang::FunctionDecl *decl) {
// TODO fix when we support builtin function (emit enreachable for now)
emit_unreachable(fn, decl);
}

void emit_unreachable(hl::FuncOp fn, const clang::FunctionDecl *decl) {
auto guard = insert_at_end(fn);
auto loc = meta_location(decl);
make< hl::UnreachableOp >(loc);
}

// TODO: This is currently just a dumb stub. But we want to be able to clearly
Expand Down Expand Up @@ -346,7 +375,6 @@ namespace vast::cg
// TODO: XRay
// TODO: PGO

//
unsigned entry_count = 0, entry_offset = 0;
if (const auto *attr = decl ? decl->getAttr< clang::PatchableFunctionEntryAttr >() : nullptr) {
VAST_UNIMPLEMENTED;
Expand Down Expand Up @@ -614,7 +642,7 @@ namespace vast::cg
if (_scope)
return;

_scope = std::unique_ptr< CodegenScope >( new CodegenScope{
_scope = std::unique_ptr< cg_scope >( new cg_scope{
.typedefs = _cgctx.typedefs,
.typedecls = _cgctx.typedecls,
.enumdecls = _cgctx.enumdecls,
Expand All @@ -624,7 +652,7 @@ namespace vast::cg
.globs = _cgctx.vars
});

_visitor = std::make_unique< CGVisitor >(_cgctx, _meta);
_visitor = std::make_unique< visitor_t >(_cgctx, _meta);
}

template< typename AST >
Expand All @@ -634,49 +662,47 @@ namespace vast::cg
}

static bool process_root_decl(void * context, const clang::Decl *decl) {
CGVisitor &visitor = *static_cast<CGVisitor*>(context);
auto &visitor = *static_cast< visitor_t* >(context);
return visitor.Visit(decl), true;
}

void process(clang::ASTUnit *unit, CGVisitor &visitor) {
void process(clang::ASTUnit *unit, visitor_t &visitor) {
unit->visitLocalTopLevelDecls(&visitor, process_root_decl);
}

void process(const clang::Decl *decl, CGVisitor &visitor) {
void process(const clang::Decl *decl, visitor_t &visitor) {
visitor.Visit(decl);
}

mcontext_t *_mctx;
MetaGenerator &_meta;
meta_generator &_meta;

CGContext &_cgctx;
std::unique_ptr< CodegenScope > _scope;
std::unique_ptr< CGVisitor > _visitor;
context_t &_cgctx;
std::unique_ptr< cg_scope > _scope;
std::unique_ptr< visitor_t > _visitor;
};

template< typename Derived >
using DefaultVisitorConfig = FallBackVisitor< Derived,
DefaultCodeGenVisitor,
UnsupportedVisitor,
UnreachableVisitor
template< typename derived_t >
using default_visitor_stack = fallback_visitor< derived_t,
default_visitor, unsup_visitor, unreach_visitor
>;

//
// CodeGen
//
template<
typename CGContext,
template< typename > typename VisitorConfig,
typename MetaGenerator
typename context_t,
template< typename > typename visitor_config,
typename meta_generator
>
struct CodeGen
struct codegen_instance
{
using CGVisitor = CodeGenVisitor< CGContext, VisitorConfig, MetaGenerator >;
using Base = CodeGenBase< CGVisitor, CGContext >;
using visitor_t = visitor_instance< context_t, visitor_config, meta_generator >;
using codegen_base = codegen_base< visitor_t, context_t >;

using VarTable = typename CGContext::VarTable;
using var_table = typename context_t::var_table;

CodeGen(CGContext &cgctx)
codegen_instance(context_t &cgctx)
: meta(&cgctx.actx, &cgctx.mctx), codegen(cgctx, meta)
{}

Expand Down Expand Up @@ -741,7 +767,7 @@ namespace vast::cg
return codegen.receive_deferred_decls_to_emit();
}

VarTable & variables_symbol_table() {
var_table & variables_symbol_table() {
return codegen.variables_symbol_table();
}

Expand All @@ -761,10 +787,22 @@ namespace vast::cg
return codegen.emit_function_prologue(fn, decl, fty_info, args, options);
}

void emit_implicit_return_zero(hl::FuncOp fn, const clang::FunctionDecl *decl) {
return codegen.emit_implicit_return_zero(fn, decl);
}

void emit_implicit_void_return(hl::FuncOp fn, const clang::FunctionDecl *decl) {
return codegen.emit_implicit_void_return(fn, decl);
}

void emit_trap(hl::FuncOp fn, const clang::FunctionDecl *decl) {
return codegen.emit_trap(fn, decl);
}

void emit_unreachable(hl::FuncOp fn, const clang::FunctionDecl *decl) {
return codegen.emit_unreachable(fn, decl);
}

hl::FuncOp declare(const clang::FunctionDecl *decl, auto vast_decl_builder) {
return codegen.declare(decl, vast_decl_builder);
}
Expand Down Expand Up @@ -815,11 +853,11 @@ namespace vast::cg

void dump_module() { codegen.dump_module(); }

MetaGenerator meta;
CodeGenBase< CGVisitor, CGContext > codegen;
meta_generator meta;
codegen_base codegen;
};

using DefaultCodeGen = CodeGen< CodeGenContext, DefaultVisitorConfig, DefaultMetaGenerator >;
using CodeGenWithMetaIDs = CodeGen< CodeGenContext, DefaultVisitorConfig, IDMetaGenerator >;
using default_codegen = codegen_instance< codegen_context, default_visitor_stack, default_meta_gen >;
using codegen_with_meta_ids = codegen_instance< codegen_context, default_visitor_stack, id_meta_gen >;

} // namespace vast::cg
36 changes: 15 additions & 21 deletions include/vast/CodeGen/CodeGenAttrVisitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "vast/Util/Warnings.hpp"

VAST_RELAX_WARNINGS
#include <clang/AST/AttrVisitor.h>
#include <clang/AST/Attr.h>
#include <clang/Basic/Diagnostic.h>
#include <clang/Frontend/FrontendDiagnostic.h>
Expand All @@ -18,30 +17,25 @@ VAST_UNRELAX_WARNINGS

namespace vast::cg {

template< typename Derived >
struct CodeGenAttrVisitor
: clang::ConstAttrVisitor< CodeGenAttrVisitor< Derived >, mlir_attr >
, CodeGenVisitorLens< CodeGenAttrVisitor< Derived >, Derived >
, CodeGenBuilder< CodeGenAttrVisitor< Derived >, Derived >
template< typename derived_t >
struct default_attr_visitor
: attr_visitor_base< default_attr_visitor< derived_t > >
, visitor_lens< derived_t, default_attr_visitor >
{
using LensType = CodeGenVisitorLens< CodeGenAttrVisitor< Derived >, Derived >;
using lens = visitor_lens< derived_t, default_attr_visitor >;

using LensType::derived;
using LensType::context;
using LensType::mcontext;
using LensType::acontext;
using lens::derived;
using lens::context;
using lens::mcontext;
using lens::acontext;

using LensType::visit;
using lens::visit;

using LensType::meta_location;

using Builder = CodeGenBuilder< CodeGenAttrVisitor< Derived >, Derived >;

using Builder::builder;

template< typename Attr, typename... Args >
auto make(Args &&...args) {
return builder().template getAttr< Attr >(std::forward< Args >(args)...);
template< typename attr_t, typename... args_t >
auto make(args_t &&...args) {
return derived().base_builder().template getAttr< attr_t >(
std::forward< args_t >(args)...
);
}

mlir_attr VisitSectionAttr(const clang::SectionAttr *attr) {
Expand Down
Loading