Skip to content

Commit

Permalink
Add a bunch of codegen infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
MikePopoloski committed Mar 21, 2020
1 parent 62fb1a9 commit ced646f
Show file tree
Hide file tree
Showing 11 changed files with 393 additions and 63 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_compile_options(/permissive-)
add_compile_options(/Zc:inline)
add_compile_options(/Gy) # Function-level linking
add_compile_options(/D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING)

# Ignore warnings in external headers
add_compile_options(/experimental:external /external:anglebrackets /external:W0)
Expand Down
45 changes: 44 additions & 1 deletion include/slang/codegen/CodeGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,77 @@
//------------------------------------------------------------------------------
#pragma once

#include <flat_hash_map.hpp>
#include <memory>
#include <string>
#include <vector>

#include "slang/util/Util.h"

namespace llvm {

class BasicBlock;
class Constant;
class Function;
class LLVMContext;
class Module;
class Type;
class Value;

} // namespace llvm

namespace slang {

class Compilation;
class ConstantValue;
class Expression;
class InstanceSymbol;
class ProceduralBlockSymbol;
class Statement;
class SubroutineSymbol;
class SVInt;
class Symbol;
class SystemSubroutine;
class Type;
class VariableSymbol;

struct CodegenOptions {
uint32_t maxIntBits = 128;
bool flattenFourState = false;
};

class CodeGenerator {
public:
CodeGenerator(Compilation& compilation);
~CodeGenerator();

std::string run(const Symbol& symbol);
std::string finish();

void genInstance(const InstanceSymbol& instance);
void genStmt(llvm::BasicBlock* bb, const Statement& stmt);

llvm::Constant* genConstant(const Type& type, const ConstantValue& cv);
llvm::Constant* genConstant(const Type& type, const SVInt& integer);
llvm::Type* genType(const Type& type);
llvm::Value* genExpr(llvm::BasicBlock* bb, const Expression& expr);
llvm::Function* genSubroutine(const SubroutineSymbol& subroutine);
llvm::Function* genSubroutine(const SystemSubroutine& subroutine);

private:
void genGlobal(const VariableSymbol& variable);
void genBlock(const ProceduralBlockSymbol& variable);

std::unique_ptr<llvm::LLVMContext> ctx;
std::unique_ptr<llvm::Module> module;
flat_hash_map<const Type*, llvm::Type*> typeMap;
flat_hash_map<const Symbol*, llvm::Value*> globalMap;
flat_hash_map<const SubroutineSymbol*, llvm::Function*> userSubroutineMap;
flat_hash_map<const SystemSubroutine*, llvm::Function*> sysSubroutineMap;
llvm::BasicBlock* globalInitBlock;
std::vector<llvm::BasicBlock*> initialBlocks;
llvm::Function* mainFunc;
Compilation& compilation;
CodegenOptions options;
};

} // namespace slang
41 changes: 41 additions & 0 deletions include/slang/codegen/ExpressionEmitter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//------------------------------------------------------------------------------
//! @file ExpressionEmitter.h
//! @brief Code emitter for expression trees
//! @note Only included if slang is configured to use LLVM
//
// File is under the MIT license; see LICENSE for details
//------------------------------------------------------------------------------
#pragma once

#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/IRBuilder.h>

#include "slang/symbols/ASTVisitor.h"

namespace slang {

class CodeGenerator;

class ExpressionEmitter {
public:
ExpressionEmitter(CodeGenerator& generator, llvm::BasicBlock* bb);

llvm::Value* emit(const Expression& expr);

// TODO: remove once all expressions are handled
template<typename T>
llvm::Value* visit(const T& expr) { return getUndef(*expr.type); }

llvm::Value* visit(const IntegerLiteral& expr);
llvm::Value* visit(const CallExpression& expr);

llvm::Value* visitInvalid(const Expression&) { return ir.CreateUnreachable(); }

private:
llvm::Value* getUndef(const Type& type);

CodeGenerator& generator;
llvm::IRBuilder<> ir;
};

} // namespace slang
38 changes: 38 additions & 0 deletions include/slang/codegen/StatementEmitter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//------------------------------------------------------------------------------
//! @file StatementEmitter.h
//! @brief Code emitter for statements
//! @note Only included if slang is configured to use LLVM
//
// File is under the MIT license; see LICENSE for details
//------------------------------------------------------------------------------
#pragma once

#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/IRBuilder.h>

#include "slang/binding/Statements.h"

namespace slang {

class CodeGenerator;

class StatementEmitter {
public:
StatementEmitter(CodeGenerator& generator, llvm::BasicBlock* bb);

void emit(const Statement& stmt);

// TODO: remove once all statements are handled
template<typename T>
void visit(const T&) {}

void visit(const ExpressionStatement& stmt);

void visitInvalid(const Statement&) {}

private:
CodeGenerator& generator;
llvm::IRBuilder<> ir;
};

} // namespace slang
28 changes: 28 additions & 0 deletions include/slang/codegen/SystemCallEmitter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//------------------------------------------------------------------------------
//! @file SystemCallEmitter.h
//! @brief Code emitter for system calls (tasks and functions)
//! @note Only included if slang is configured to use LLVM
//
// File is under the MIT license; see LICENSE for details
//------------------------------------------------------------------------------
#pragma once

#include <flat_hash_map.hpp>
#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/IRBuilder.h>

#include "slang/util/Util.h"

namespace slang {

class CodeGenerator;
class Expression;
class Scope;
class SystemSubroutine;

class SystemCallEmitter {
public:
private:
};

} // namespace slang
7 changes: 6 additions & 1 deletion source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,12 @@ add_library(slang
)

if(SLANG_INCLUDE_LLVM)
target_sources(slang PRIVATE codegen/CodeGenerator.cpp)
target_sources(slang PRIVATE
codegen/CodeGenerator.cpp
codegen/ExpressionEmitter.cpp
codegen/StatementEmitter.cpp
codegen/SystemCallEmitter.cpp
)
endif()

add_dependencies(slang gen_version)
Expand Down
Loading

0 comments on commit ced646f

Please sign in to comment.