finalize ep 12
This commit is contained in:
parent
5622b4de0c
commit
69e8782c67
|
@ -169,10 +169,12 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||||
# LLVM setup =========================================
|
# LLVM setup =========================================
|
||||||
find_package(LLVM REQUIRED CONFIG)
|
find_package(LLVM REQUIRED CONFIG)
|
||||||
find_package(MLIR REQUIRED CONFIG)
|
find_package(MLIR REQUIRED CONFIG)
|
||||||
|
find_package(LLD REQUIRED CONFIG)
|
||||||
|
|
||||||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
||||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
||||||
message(STATUS "Using MLIRConfig.cmake in: ${MLIR_DIR}")
|
message(STATUS "Using MLIRConfig.cmake in: ${MLIR_DIR}")
|
||||||
|
message(STATUS "Using LLDConfig.cmake in: ${LLD_DIR}")
|
||||||
|
|
||||||
set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/bin)
|
set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/bin)
|
||||||
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/lib)
|
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
@ -180,15 +182,15 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${MLIR_CMAKE_DIR}")
|
list(APPEND CMAKE_MODULE_PATH "${MLIR_CMAKE_DIR}")
|
||||||
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
|
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${LLD_CMAKE_DIR}")
|
||||||
|
|
||||||
include(TableGen)
|
include(TableGen)
|
||||||
include(AddLLVM)
|
include(AddLLVM)
|
||||||
include(AddMLIR)
|
include(AddMLIR)
|
||||||
include(HandleLLVMOptions)
|
include(HandleLLVMOptions)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
include_directories(SYSTEM ${LLVM_INCLUDE_DIRS})
|
include_directories(SYSTEM ${LLVM_INCLUDE_DIRS})
|
||||||
|
|
||||||
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
|
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
|
||||||
add_definitions(${LLVM_DEFINITIONS_LIST})
|
add_definitions(${LLVM_DEFINITIONS_LIST})
|
||||||
|
|
||||||
|
|
|
@ -517,6 +517,7 @@ This framework allows for transforming a set of illegal operations to a set of l
|
||||||
** Next Step
|
** Next Step
|
||||||
*** Compile to object files
|
*** Compile to object files
|
||||||
*** Link object files to create an executable
|
*** Link object files to create an executable
|
||||||
|
** End of wiring for static compilers
|
||||||
** What is an object file?
|
** What is an object file?
|
||||||
*** Symbols
|
*** Symbols
|
||||||
- A pair of a name and a value
|
- A pair of a name and a value
|
||||||
|
@ -558,3 +559,5 @@ and tries to =resolve= *undefined* symbols
|
||||||
+ write the result to a file as an executable
|
+ write the result to a file as an executable
|
||||||
** AOT vs JIT
|
** AOT vs JIT
|
||||||
** Let's look at some code
|
** Let's look at some code
|
||||||
|
** Resources:
|
||||||
|
- [[https://lwn.net/Articles/276782/][20 part linker essay]]
|
||||||
|
|
|
@ -43,7 +43,8 @@ target_link_libraries(serenec
|
||||||
|
|
||||||
LLVMTarget
|
LLVMTarget
|
||||||
LLVMOption
|
LLVMOption
|
||||||
|
lldDriver
|
||||||
|
lldELF
|
||||||
clangDriver
|
clangDriver
|
||||||
clangBasic
|
clangBasic
|
||||||
clangdSupport
|
clangdSupport
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "serene/slir/generatable.h"
|
#include "serene/slir/generatable.h"
|
||||||
#include "serene/slir/slir.h"
|
#include "serene/slir/slir.h"
|
||||||
|
|
||||||
|
#include <lld/Common/Driver.h>
|
||||||
|
|
||||||
#include <clang/Driver/Compilation.h>
|
#include <clang/Driver/Compilation.h>
|
||||||
#include <clang/Driver/Driver.h>
|
#include <clang/Driver/Driver.h>
|
||||||
#include <clang/Frontend/TextDiagnosticPrinter.h>
|
#include <clang/Frontend/TextDiagnosticPrinter.h>
|
||||||
|
@ -176,182 +178,218 @@ int dumpAsObject(Namespace &ns) {
|
||||||
dest.flush();
|
dest.flush();
|
||||||
|
|
||||||
if (emitAction == Action::Compile) {
|
if (emitAction == Action::Compile) {
|
||||||
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> opts =
|
|
||||||
new clang::DiagnosticOptions;
|
|
||||||
clang::DiagnosticsEngine diags(
|
|
||||||
new clang::DiagnosticIDs, opts,
|
|
||||||
new clang::TextDiagnosticPrinter(llvm::errs(), opts.get()));
|
|
||||||
|
|
||||||
clang::driver::Driver d("clang", ctx.targetTriple, diags,
|
|
||||||
"Serene compiler");
|
|
||||||
std::vector<const char *> args = {"serenec"};
|
std::vector<const char *> args = {"serenec"};
|
||||||
|
|
||||||
|
args.push_back("--eh-frame-hdr");
|
||||||
|
args.push_back("-m");
|
||||||
|
args.push_back("elf_x86_64");
|
||||||
|
args.push_back("-dynamic-linker");
|
||||||
|
args.push_back("/lib64/ld-linux-x86-64.so.2");
|
||||||
|
args.push_back(
|
||||||
|
"/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib64/crt1.o");
|
||||||
|
args.push_back(
|
||||||
|
"/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib64/crti.o");
|
||||||
|
args.push_back("/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/crtbegin.o");
|
||||||
|
args.push_back("-L");
|
||||||
|
args.push_back("/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/");
|
||||||
|
args.push_back("-L");
|
||||||
|
args.push_back("/usr/lib64/");
|
||||||
|
|
||||||
args.push_back(destObjFilePath.c_str());
|
args.push_back(destObjFilePath.c_str());
|
||||||
args.push_back("-o");
|
args.push_back("-o");
|
||||||
args.push_back(destFile.c_str());
|
args.push_back(destFile.c_str());
|
||||||
|
args.push_back("-lgcc");
|
||||||
|
args.push_back("--as-needed");
|
||||||
|
args.push_back("-lgcc_s");
|
||||||
|
args.push_back("--no-as-needed");
|
||||||
|
args.push_back("-lc");
|
||||||
|
args.push_back("-lgcc");
|
||||||
|
args.push_back("--as-needed");
|
||||||
|
args.push_back("-lgcc_s");
|
||||||
|
args.push_back("--no-as-needed");
|
||||||
|
args.push_back("/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/crtend.o");
|
||||||
|
args.push_back(
|
||||||
|
"/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib64/crtn.o");
|
||||||
|
|
||||||
d.setCheckInputsExist(true);
|
lld::elf::link(args, false, llvm::outs(), llvm::errs());
|
||||||
|
|
||||||
std::unique_ptr<clang::driver::Compilation> compilation;
|
// llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> opts =
|
||||||
compilation.reset(d.BuildCompilation(args));
|
// new clang::DiagnosticOptions;
|
||||||
|
// clang::DiagnosticsEngine diags(
|
||||||
|
// new clang::DiagnosticIDs, opts,
|
||||||
|
// new clang::TextDiagnosticPrinter(llvm::errs(), opts.get()));
|
||||||
|
|
||||||
if (!compilation) {
|
// clang::driver::Driver d("clang", ctx.targetTriple, diags,
|
||||||
llvm::errs() << "can't create the compilation!\n";
|
// "Serene compiler");
|
||||||
|
// std::vector<const char *> args = {"serenec"};
|
||||||
|
|
||||||
|
// args.push_back(destObjFilePath.c_str());
|
||||||
|
// args.push_back("-o");
|
||||||
|
// args.push_back(destFile.c_str());
|
||||||
|
|
||||||
|
// d.setCheckInputsExist(true);
|
||||||
|
|
||||||
|
// std::unique_ptr<clang::driver::Compilation> compilation;
|
||||||
|
// compilation.reset(d.BuildCompilation(args));
|
||||||
|
|
||||||
|
// if (!compilation) {
|
||||||
|
// llvm::errs() << "can't create the compilation!\n";
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// llvm::SmallVector<std::pair<int, const clang::driver::Command *>>
|
||||||
|
// failCommand;
|
||||||
|
|
||||||
|
// d.ExecuteCompilation(*compilation, failCommand);
|
||||||
|
|
||||||
|
// if (failCommand.empty()) {
|
||||||
|
// llvm::outs() << "Done!\n";
|
||||||
|
// } else {
|
||||||
|
// llvm::errs() << "Linking failed!\n";
|
||||||
|
// failCommand.front().second->Print(llvm::errs(), "\n", false);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
initCompiler();
|
||||||
|
registerSereneCLOptions();
|
||||||
|
|
||||||
|
cl::ParseCommandLineOptions(argc, argv, banner);
|
||||||
|
|
||||||
|
auto ctx = makeSereneContext();
|
||||||
|
auto userNS = makeNamespace(*ctx, "user", llvm::None);
|
||||||
|
|
||||||
|
applySereneCLOptions(*ctx);
|
||||||
|
|
||||||
|
// TODO: handle the outputDir by not forcing it. it should be
|
||||||
|
// default to the current working dir
|
||||||
|
if (outputDir == "-") {
|
||||||
|
llvm::errs()
|
||||||
|
<< "Error: The build directory is not set. Did you forget to "
|
||||||
|
"use '-b'?\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::SmallVector<std::pair<int, const clang::driver::Command *>>
|
switch (emitAction) {
|
||||||
failCommand;
|
|
||||||
|
|
||||||
d.ExecuteCompilation(*compilation, failCommand);
|
case Action::RunJIT: {
|
||||||
|
// TODO: Replace it by a proper jit configuration
|
||||||
|
ctx->setOperationPhase(CompilationPhase::NoOptimization);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
if (failCommand.empty()) {
|
// Just print out the raw AST
|
||||||
llvm::outs() << "Done!\n";
|
case Action::DumpAST: {
|
||||||
} else {
|
ctx->setOperationPhase(CompilationPhase::Parse);
|
||||||
llvm::errs() << "Linking failed!\n";
|
break;
|
||||||
failCommand.front().second->Print(llvm::errs(), "\n", false);
|
};
|
||||||
|
|
||||||
|
case Action::DumpSemantic: {
|
||||||
|
ctx->setOperationPhase(CompilationPhase::Analysis);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
case Action::DumpSLIR: {
|
||||||
|
ctx->setOperationPhase(CompilationPhase::SLIR);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
case Action::DumpMLIR: {
|
||||||
};
|
ctx->setOperationPhase(CompilationPhase::MLIR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
case Action::DumpLIR: {
|
||||||
initCompiler();
|
ctx->setOperationPhase(CompilationPhase::LIR);
|
||||||
registerSereneCLOptions();
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
cl::ParseCommandLineOptions(argc, argv, banner);
|
case Action::DumpIR: {
|
||||||
|
ctx->setOperationPhase(CompilationPhase::IR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
auto ctx = makeSereneContext();
|
case Action::CompileToObject: {
|
||||||
auto userNS = makeNamespace(*ctx, "user", llvm::None);
|
ctx->setOperationPhase(CompilationPhase::NoOptimization);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
applySereneCLOptions(*ctx);
|
case Action::Compile: {
|
||||||
|
ctx->setOperationPhase(CompilationPhase::NoOptimization);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: handle the outputDir by not forcing it. it should be
|
default: {
|
||||||
// default to the current working dir
|
llvm::errs() << "No action specified. TODO: Print out help here\n";
|
||||||
if (outputDir == "-") {
|
return 1;
|
||||||
llvm::errs() << "Error: The build directory is not set. Did you forget to "
|
}
|
||||||
"use '-b'?\n";
|
}
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (emitAction) {
|
auto runLoc = reader::LocationRange::UnknownLocation(inputNS);
|
||||||
|
auto maybeNS = ctx->sourceManager.readNamespace(*ctx, inputNS, runLoc);
|
||||||
|
|
||||||
case Action::RunJIT: {
|
if (!maybeNS) {
|
||||||
// TODO: Replace it by a proper jit configuration
|
throwErrors(*ctx, maybeNS.getError());
|
||||||
ctx->setOperationPhase(CompilationPhase::NoOptimization);
|
return (int)std::errc::no_such_file_or_directory;
|
||||||
break;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// Just print out the raw AST
|
auto ns = maybeNS.getValue();
|
||||||
case Action::DumpAST: {
|
|
||||||
ctx->setOperationPhase(CompilationPhase::Parse);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
case Action::DumpSemantic: {
|
ctx->insertNS(ns);
|
||||||
ctx->setOperationPhase(CompilationPhase::Analysis);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
case Action::DumpSLIR: {
|
switch (emitAction) {
|
||||||
ctx->setOperationPhase(CompilationPhase::SLIR);
|
case Action::DumpAST:
|
||||||
break;
|
case Action::DumpSemantic: {
|
||||||
}
|
auto ast = ns->getTree();
|
||||||
|
llvm::outs() << exprs::astToString(&ast) << "\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
case Action::DumpMLIR: {
|
case Action::DumpSLIR:
|
||||||
ctx->setOperationPhase(CompilationPhase::MLIR);
|
case Action::DumpMLIR:
|
||||||
break;
|
case Action::DumpLIR: {
|
||||||
}
|
ns->dump();
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case Action::DumpIR: {
|
||||||
|
auto maybeModule = ns->compileToLLVM();
|
||||||
|
|
||||||
case Action::DumpLIR: {
|
if (!maybeModule) {
|
||||||
ctx->setOperationPhase(CompilationPhase::LIR);
|
llvm::errs() << "Failed to generate the IR.\n";
|
||||||
break;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Action::DumpIR: {
|
maybeModule.getValue()->dump();
|
||||||
ctx->setOperationPhase(CompilationPhase::IR);
|
break;
|
||||||
break;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
case Action::CompileToObject: {
|
case Action::RunJIT: {
|
||||||
ctx->setOperationPhase(CompilationPhase::NoOptimization);
|
auto maybeJIT = JIT::make(*ns);
|
||||||
break;
|
if (!maybeJIT) {
|
||||||
}
|
// TODO: panic in here: "Couldn't creat the JIT!"
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
auto jit = std::move(maybeJIT.getValue());
|
||||||
|
|
||||||
case Action::Compile: {
|
if (jit->invoke("main")) {
|
||||||
ctx->setOperationPhase(CompilationPhase::NoOptimization);
|
llvm::errs() << "Faild to invoke the 'main' function.\n";
|
||||||
break;
|
return 1;
|
||||||
}
|
}
|
||||||
|
llvm::outs() << "Done!";
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
default: {
|
case Action::Compile:
|
||||||
llvm::errs() << "No action specified. TODO: Print out help here\n";
|
case Action::CompileToObject: {
|
||||||
return 1;
|
return dumpAsObject(*ns);
|
||||||
}
|
};
|
||||||
}
|
default: {
|
||||||
|
llvm::errs() << "Action is not supported yet!\n";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
auto runLoc = reader::LocationRange::UnknownLocation(inputNS);
|
|
||||||
auto maybeNS = ctx->sourceManager.readNamespace(*ctx, inputNS, runLoc);
|
|
||||||
|
|
||||||
if (!maybeNS) {
|
|
||||||
throwErrors(*ctx, maybeNS.getError());
|
|
||||||
return (int)std::errc::no_such_file_or_directory;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ns = maybeNS.getValue();
|
|
||||||
|
|
||||||
ctx->insertNS(ns);
|
|
||||||
|
|
||||||
switch (emitAction) {
|
|
||||||
case Action::DumpAST:
|
|
||||||
case Action::DumpSemantic: {
|
|
||||||
auto ast = ns->getTree();
|
|
||||||
llvm::outs() << exprs::astToString(&ast) << "\n";
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Action::DumpSLIR:
|
|
||||||
case Action::DumpMLIR:
|
|
||||||
case Action::DumpLIR: {
|
|
||||||
ns->dump();
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
case Action::DumpIR: {
|
|
||||||
auto maybeModule = ns->compileToLLVM();
|
|
||||||
|
|
||||||
if (!maybeModule) {
|
|
||||||
llvm::errs() << "Failed to generate the IR.\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
maybeModule.getValue()->dump();
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
case Action::RunJIT: {
|
|
||||||
auto maybeJIT = JIT::make(*ns);
|
|
||||||
if (!maybeJIT) {
|
|
||||||
// TODO: panic in here: "Couldn't creat the JIT!"
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
auto jit = std::move(maybeJIT.getValue());
|
|
||||||
|
|
||||||
if (jit->invoke("main")) {
|
|
||||||
llvm::errs() << "Faild to invoke the 'main' function.\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
llvm::outs() << "Done!";
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
case Action::Compile:
|
|
||||||
case Action::CompileToObject: {
|
|
||||||
return dumpAsObject(*ns);
|
|
||||||
};
|
|
||||||
default: {
|
|
||||||
llvm::errs() << "Action is not supported yet!\n";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue