Add support for compil to object file
This commit is contained in:
parent
a6254b0876
commit
8c19a56203
|
@ -20,6 +20,7 @@ target_link_libraries(serenec PRIVATE
|
||||||
MLIRParser
|
MLIRParser
|
||||||
MLIRSideEffectInterfaces
|
MLIRSideEffectInterfaces
|
||||||
MLIRTransforms
|
MLIRTransforms
|
||||||
|
LLVMX86AsmParser
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "serene/serene.h"
|
#include "serene/serene.h"
|
||||||
|
|
||||||
|
#include "mlir/ExecutionEngine/ExecutionEngine.h"
|
||||||
#include "serene/context.h"
|
#include "serene/context.h"
|
||||||
#include "serene/namespace.h"
|
#include "serene/namespace.h"
|
||||||
#include "serene/reader/reader.h"
|
#include "serene/reader/reader.h"
|
||||||
|
@ -31,8 +32,15 @@
|
||||||
#include "serene/slir/generatable.h"
|
#include "serene/slir/generatable.h"
|
||||||
#include "serene/slir/slir.h"
|
#include "serene/slir/slir.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <llvm/IR/LegacyPassManager.h>
|
||||||
#include <llvm/Support/CommandLine.h>
|
#include <llvm/Support/CommandLine.h>
|
||||||
|
#include <llvm/Support/FileSystem.h>
|
||||||
|
#include <llvm/Support/Host.h>
|
||||||
|
#include <llvm/Support/TargetRegistry.h>
|
||||||
|
#include <llvm/Support/TargetSelect.h>
|
||||||
|
#include <llvm/Support/raw_ostream.h>
|
||||||
|
#include <llvm/Target/TargetMachine.h>
|
||||||
|
#include <llvm/Target/TargetOptions.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -44,11 +52,12 @@ namespace {
|
||||||
enum Action {
|
enum Action {
|
||||||
None,
|
None,
|
||||||
DumpAST,
|
DumpAST,
|
||||||
DumpIR,
|
|
||||||
DumpSLIR,
|
DumpSLIR,
|
||||||
DumpMLIR,
|
DumpMLIR,
|
||||||
DumpSemantic,
|
DumpSemantic,
|
||||||
DumpLIR
|
DumpLIR,
|
||||||
|
DumpIR,
|
||||||
|
CompileToObject
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,8 +66,13 @@ static cl::opt<std::string> inputFile(cl::Positional,
|
||||||
cl::init("-"),
|
cl::init("-"),
|
||||||
cl::value_desc("filename"));
|
cl::value_desc("filename"));
|
||||||
|
|
||||||
|
static cl::opt<std::string> outputFile("o",
|
||||||
|
cl::desc("The path to the output file"),
|
||||||
|
cl::init("-"),
|
||||||
|
cl::value_desc("filename"));
|
||||||
|
|
||||||
static cl::opt<enum Action> emitAction(
|
static cl::opt<enum Action> emitAction(
|
||||||
"emit", cl::desc("Select what to dump."),
|
"emit", cl::desc("Select what to dump."), cl::init(CompileToObject),
|
||||||
cl::values(clEnumValN(DumpSemantic, "semantic",
|
cl::values(clEnumValN(DumpSemantic, "semantic",
|
||||||
"Output the AST after one level of analysis only")),
|
"Output the AST after one level of analysis only")),
|
||||||
cl::values(clEnumValN(DumpIR, "ir", "Output the lowered IR only")),
|
cl::values(clEnumValN(DumpIR, "ir", "Output the lowered IR only")),
|
||||||
|
@ -67,7 +81,9 @@ static cl::opt<enum Action> emitAction(
|
||||||
"Output the MLIR only (Lowered SLIR)")),
|
"Output the MLIR only (Lowered SLIR)")),
|
||||||
cl::values(clEnumValN(DumpLIR, "lir",
|
cl::values(clEnumValN(DumpLIR, "lir",
|
||||||
"Output the LIR only (Lowerd to LLVM dialect)")),
|
"Output the LIR only (Lowerd to LLVM dialect)")),
|
||||||
cl::values(clEnumValN(DumpAST, "ast", "Output the AST only"))
|
cl::values(clEnumValN(DumpAST, "ast", "Output the AST only")),
|
||||||
|
cl::values(clEnumValN(CompileToObject, "object",
|
||||||
|
"Compile to object file. (Default)"))
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -92,11 +108,72 @@ exprs::Ast readAndAnalyze(SereneContext &ctx) {
|
||||||
return afterAst.getValue();
|
return afterAst.getValue();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int dumpAsObject(Namespace &ns) {
|
||||||
|
|
||||||
|
auto &module = ns.getLLVMModule();
|
||||||
|
auto targetTriple = llvm::sys::getDefaultTargetTriple();
|
||||||
|
module.setTargetTriple(targetTriple);
|
||||||
|
|
||||||
|
std::string Error;
|
||||||
|
auto target = llvm::TargetRegistry::lookupTarget(targetTriple, Error);
|
||||||
|
|
||||||
|
// Print an error and exit if we couldn't find the requested target.
|
||||||
|
// This generally occurs if we've forgotten to initialise the
|
||||||
|
// TargetRegistry or we have a bogus target triple.
|
||||||
|
if (!target) {
|
||||||
|
llvm::errs() << Error;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cpu = "generic";
|
||||||
|
auto features = "";
|
||||||
|
|
||||||
|
llvm::TargetOptions opt;
|
||||||
|
auto rm = llvm::Optional<llvm::Reloc::Model>();
|
||||||
|
auto targetMachinePtr =
|
||||||
|
target->createTargetMachine(targetTriple, cpu, features, opt, rm);
|
||||||
|
auto targetMachine = std::unique_ptr<llvm::TargetMachine>(targetMachinePtr);
|
||||||
|
|
||||||
|
module.setDataLayout(targetMachine->createDataLayout());
|
||||||
|
|
||||||
|
auto filename =
|
||||||
|
strcmp(outputFile.c_str(), "-") == 0 ? "output.o" : outputFile.c_str();
|
||||||
|
|
||||||
|
std::error_code ec;
|
||||||
|
llvm::raw_fd_ostream dest(filename, ec, llvm::sys::fs::OF_None);
|
||||||
|
|
||||||
|
if (ec) {
|
||||||
|
llvm::errs() << "Could not open file: " << ec.message();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::legacy::PassManager pass;
|
||||||
|
auto fileType = llvm::CGFT_ObjectFile;
|
||||||
|
|
||||||
|
if (targetMachine->addPassesToEmitFile(pass, dest, nullptr, fileType)) {
|
||||||
|
llvm::errs() << "TheTargetMachine can't emit a file of this type";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pass.run(module);
|
||||||
|
dest.flush();
|
||||||
|
|
||||||
|
llvm::outs() << "Wrote " << filename << "\n";
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
// mlir::registerAsmPrinterCLOptions();
|
// mlir::registerAsmPrinterCLOptions();
|
||||||
mlir::registerMLIRContextCLOptions();
|
mlir::registerMLIRContextCLOptions();
|
||||||
mlir::registerPassManagerCLOptions();
|
mlir::registerPassManagerCLOptions();
|
||||||
|
|
||||||
|
llvm::InitializeAllTargetInfos();
|
||||||
|
llvm::InitializeAllTargets();
|
||||||
|
llvm::InitializeAllTargetMCs();
|
||||||
|
llvm::InitializeAllAsmParsers();
|
||||||
|
llvm::InitializeAllAsmPrinters();
|
||||||
|
|
||||||
cl::ParseCommandLineOptions(argc, argv, "Serene compiler \n");
|
cl::ParseCommandLineOptions(argc, argv, "Serene compiler \n");
|
||||||
auto ctx = makeSereneContext();
|
auto ctx = makeSereneContext();
|
||||||
auto ns = makeNamespace(*ctx, "user", llvm::None);
|
auto ns = makeNamespace(*ctx, "user", llvm::None);
|
||||||
|
@ -137,6 +214,11 @@ int main(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Action::CompileToObject: {
|
||||||
|
ctx->setOperationPhase(CompilationPhase::NoOptimization);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
llvm::errs() << "No action specified. TODO: Print out help here\n";
|
llvm::errs() << "No action specified. TODO: Print out help here\n";
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -152,7 +234,11 @@ int main(int argc, char *argv[]) {
|
||||||
llvm::errs() << "IR generation faild\n";
|
llvm::errs() << "IR generation faild\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (emitAction < CompileToObject) {
|
||||||
serene::slir::dump<Namespace>(*ns);
|
serene::slir::dump<Namespace>(*ns);
|
||||||
|
} else {
|
||||||
|
return dumpAsObject(*ns);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
llvm::outs() << "Can't set the tree of the namespace!\n";
|
llvm::outs() << "Can't set the tree of the namespace!\n";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue