Add the 'target' emit action as a temporary action to generate target code
This commit is contained in:
parent
f8b66934a1
commit
e00156b9e7
|
@ -32,6 +32,10 @@
|
||||||
#include "serene/slir/generatable.h"
|
#include "serene/slir/generatable.h"
|
||||||
#include "serene/slir/slir.h"
|
#include "serene/slir/slir.h"
|
||||||
|
|
||||||
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
#include "llvm/ADT/SmallString.h"
|
||||||
|
#include "llvm/ADT/StringRef.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>
|
||||||
|
@ -41,6 +45,7 @@
|
||||||
#include <llvm/Support/FileSystem.h>
|
#include <llvm/Support/FileSystem.h>
|
||||||
#include <llvm/Support/FormatVariadic.h>
|
#include <llvm/Support/FormatVariadic.h>
|
||||||
#include <llvm/Support/Host.h>
|
#include <llvm/Support/Host.h>
|
||||||
|
#include <llvm/Support/Path.h>
|
||||||
#include <llvm/Support/TargetRegistry.h>
|
#include <llvm/Support/TargetRegistry.h>
|
||||||
#include <llvm/Support/TargetSelect.h>
|
#include <llvm/Support/TargetSelect.h>
|
||||||
#include <llvm/Support/raw_ostream.h>
|
#include <llvm/Support/raw_ostream.h>
|
||||||
|
@ -62,7 +67,8 @@ enum Action {
|
||||||
DumpSemantic,
|
DumpSemantic,
|
||||||
DumpLIR,
|
DumpLIR,
|
||||||
DumpIR,
|
DumpIR,
|
||||||
CompileToObject
|
CompileToObject,
|
||||||
|
Compile,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,13 +77,16 @@ 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",
|
static cl::opt<std::string> outputFile(
|
||||||
cl::desc("The path to the output file"),
|
"o", cl::desc("The relative path to the output file from the build dir"),
|
||||||
cl::init("-"),
|
cl::init("-"), cl::value_desc("filename"));
|
||||||
cl::value_desc("filename"));
|
|
||||||
|
static cl::opt<std::string>
|
||||||
|
outputDir("build-dir", cl::desc("The absolute path to the build directory"),
|
||||||
|
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."), cl::init(CompileToObject),
|
"emit", cl::desc("Select what to dump."), cl::init(Compile),
|
||||||
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")),
|
||||||
|
@ -88,7 +97,9 @@ static cl::opt<enum Action> emitAction(
|
||||||
"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",
|
cl::values(clEnumValN(CompileToObject, "object",
|
||||||
"Compile to object file. (Default)"))
|
"Compile to object file.")),
|
||||||
|
cl::values(clEnumValN(Compile, "target",
|
||||||
|
"Compile to target code. (Default)"))
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -114,13 +125,13 @@ exprs::Ast readAndAnalyze(SereneContext &ctx) {
|
||||||
};
|
};
|
||||||
|
|
||||||
int dumpAsObject(Namespace &ns) {
|
int dumpAsObject(Namespace &ns) {
|
||||||
|
// TODO: Move the compilation process to the Namespace class
|
||||||
auto &module = ns.getLLVMModule();
|
auto &module = ns.getLLVMModule();
|
||||||
auto targetTriple = llvm::sys::getDefaultTargetTriple();
|
auto &ctx = ns.getContext();
|
||||||
module.setTargetTriple(targetTriple);
|
module.setTargetTriple(ctx.targetTriple);
|
||||||
|
|
||||||
std::string Error;
|
std::string Error;
|
||||||
auto target = llvm::TargetRegistry::lookupTarget(targetTriple, Error);
|
auto target = llvm::TargetRegistry::lookupTarget(ctx.targetTriple, Error);
|
||||||
|
|
||||||
// Print an error and exit if we couldn't find the requested target.
|
// Print an error and exit if we couldn't find the requested target.
|
||||||
// This generally occurs if we've forgotten to initialise the
|
// This generally occurs if we've forgotten to initialise the
|
||||||
|
@ -136,7 +147,7 @@ int dumpAsObject(Namespace &ns) {
|
||||||
llvm::TargetOptions opt;
|
llvm::TargetOptions opt;
|
||||||
auto rm = llvm::Optional<llvm::Reloc::Model>();
|
auto rm = llvm::Optional<llvm::Reloc::Model>();
|
||||||
auto targetMachinePtr =
|
auto targetMachinePtr =
|
||||||
target->createTargetMachine(targetTriple, cpu, features, opt, rm);
|
target->createTargetMachine(ctx.targetTriple, cpu, features, opt, rm);
|
||||||
auto targetMachine = std::unique_ptr<llvm::TargetMachine>(targetMachinePtr);
|
auto targetMachine = std::unique_ptr<llvm::TargetMachine>(targetMachinePtr);
|
||||||
|
|
||||||
module.setDataLayout(targetMachine->createDataLayout());
|
module.setDataLayout(targetMachine->createDataLayout());
|
||||||
|
@ -145,8 +156,10 @@ int dumpAsObject(Namespace &ns) {
|
||||||
strcmp(outputFile.c_str(), "-") == 0 ? "output" : outputFile.c_str();
|
strcmp(outputFile.c_str(), "-") == 0 ? "output" : outputFile.c_str();
|
||||||
|
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
llvm::raw_fd_ostream dest(llvm::formatv("{0}.o", filename).str(), ec,
|
llvm::SmallString<256> destFile(outputDir);
|
||||||
llvm::sys::fs::OF_None);
|
llvm::sys::path::append(destFile, filename);
|
||||||
|
auto destObjFilePath = llvm::formatv("{0}.o", destFile).str();
|
||||||
|
llvm::raw_fd_ostream dest(destObjFilePath, ec, llvm::sys::fs::OF_None);
|
||||||
|
|
||||||
if (ec) {
|
if (ec) {
|
||||||
llvm::errs() << "Could not open file: " << ec.message();
|
llvm::errs() << "Could not open file: " << ec.message();
|
||||||
|
@ -164,22 +177,20 @@ int dumpAsObject(Namespace &ns) {
|
||||||
pass.run(module);
|
pass.run(module);
|
||||||
dest.flush();
|
dest.flush();
|
||||||
|
|
||||||
llvm::outs() << "Wrote " << filename << "\n";
|
if (emitAction == Action::Compile) {
|
||||||
|
|
||||||
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> opts =
|
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> opts =
|
||||||
new clang::DiagnosticOptions;
|
new clang::DiagnosticOptions;
|
||||||
clang::DiagnosticsEngine diags(
|
clang::DiagnosticsEngine diags(
|
||||||
new clang::DiagnosticIDs, opts,
|
new clang::DiagnosticIDs, opts,
|
||||||
new clang::TextDiagnosticPrinter(llvm::errs(), opts.get()));
|
new clang::TextDiagnosticPrinter(llvm::errs(), opts.get()));
|
||||||
|
|
||||||
clang::driver::Driver d("clang", targetTriple, diags, "Serene compiler");
|
clang::driver::Driver d("clang", ctx.targetTriple, diags,
|
||||||
std::vector<const char *> args = {"hnt"};
|
"Serene compiler");
|
||||||
auto objf =
|
std::vector<const char *> args = {"serenec"};
|
||||||
llvm::formatv("/home/lxsameer/src/serene/serene/build/{0}.o", filename)
|
|
||||||
.str();
|
args.push_back(destObjFilePath.c_str());
|
||||||
args.push_back(objf.c_str());
|
|
||||||
args.push_back("-o");
|
args.push_back("-o");
|
||||||
args.push_back(filename);
|
args.push_back(destFile.c_str());
|
||||||
|
|
||||||
d.setCheckInputsExist(false);
|
d.setCheckInputsExist(false);
|
||||||
|
|
||||||
|
@ -190,7 +201,8 @@ int dumpAsObject(Namespace &ns) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::SmallVector<std::pair<int, const clang::driver::Command *>> failCommand;
|
llvm::SmallVector<std::pair<int, const clang::driver::Command *>>
|
||||||
|
failCommand;
|
||||||
// compilation->ExecuteJobs(compilation->getJobs(), failCommand);
|
// compilation->ExecuteJobs(compilation->getJobs(), failCommand);
|
||||||
|
|
||||||
d.ExecuteCompilation(*compilation, failCommand);
|
d.ExecuteCompilation(*compilation, failCommand);
|
||||||
|
@ -199,15 +211,8 @@ int dumpAsObject(Namespace &ns) {
|
||||||
} else {
|
} else {
|
||||||
llvm::errs() << "Linking failed!\n";
|
llvm::errs() << "Linking failed!\n";
|
||||||
}
|
}
|
||||||
// const llvm::opt::ArgStringList *const cc1Args = n
|
}
|
||||||
// getCC1Arguments(&diags, compilation.get());
|
|
||||||
// if (!cc1Args)
|
|
||||||
// return 2;
|
|
||||||
// std::unique_ptr<clang::CompilerInvocation> Invocation(
|
|
||||||
// clang::tooling::newInvocation(&diags, *cc1Args, "hnt"));
|
|
||||||
// return clang::tooling::runInvocation("hnt", compilation.get(),
|
|
||||||
// std::move(Invocation),
|
|
||||||
// std::move(PCHContainerOps));
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -227,6 +232,15 @@ int main(int argc, char *argv[]) {
|
||||||
auto ns = makeNamespace(*ctx, "user", llvm::None);
|
auto ns = makeNamespace(*ctx, "user", llvm::None);
|
||||||
// TODO: We might want to find a better place for this
|
// TODO: We might want to find a better place for this
|
||||||
applyPassManagerCLOptions(ctx->pm);
|
applyPassManagerCLOptions(ctx->pm);
|
||||||
|
|
||||||
|
// 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 '-build-dir'?\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
switch (emitAction) {
|
switch (emitAction) {
|
||||||
|
|
||||||
// Just print out the raw AST
|
// Just print out the raw AST
|
||||||
|
@ -267,6 +281,11 @@ int main(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Action::Compile: {
|
||||||
|
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;
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "serene/slir/dialect.h"
|
#include "serene/slir/dialect.h"
|
||||||
|
|
||||||
#include <llvm/ADT/StringRef.h>
|
#include <llvm/ADT/StringRef.h>
|
||||||
|
#include <llvm/Support/Host.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mlir/Dialect/StandardOps/IR/Ops.h>
|
#include <mlir/Dialect/StandardOps/IR/Ops.h>
|
||||||
#include <mlir/IR/MLIRContext.h>
|
#include <mlir/IR/MLIRContext.h>
|
||||||
|
@ -65,6 +66,7 @@ public:
|
||||||
llvm::LLVMContext llvmContext;
|
llvm::LLVMContext llvmContext;
|
||||||
mlir::MLIRContext mlirContext;
|
mlir::MLIRContext mlirContext;
|
||||||
mlir::PassManager pm;
|
mlir::PassManager pm;
|
||||||
|
std::string targetTriple;
|
||||||
|
|
||||||
/// Insert the given `ns` into the context. The Context object is
|
/// Insert the given `ns` into the context. The Context object is
|
||||||
/// the owner of all the namespaces. The `ns` will overwrite any
|
/// the owner of all the namespaces. The `ns` will overwrite any
|
||||||
|
@ -84,7 +86,9 @@ public:
|
||||||
: pm(&mlirContext), targetPhase(CompilationPhase::NoOptimization) {
|
: pm(&mlirContext), targetPhase(CompilationPhase::NoOptimization) {
|
||||||
mlirContext.getOrLoadDialect<serene::slir::SereneDialect>();
|
mlirContext.getOrLoadDialect<serene::slir::SereneDialect>();
|
||||||
mlirContext.getOrLoadDialect<mlir::StandardOpsDialect>();
|
mlirContext.getOrLoadDialect<mlir::StandardOpsDialect>();
|
||||||
|
// TODO: Get the crash report path dynamically from the cli
|
||||||
pm.enableCrashReproducerGeneration("/home/lxsameer/mlir.mlir");
|
pm.enableCrashReproducerGeneration("/home/lxsameer/mlir.mlir");
|
||||||
|
targetTriple = llvm::sys::getDefaultTargetTriple();
|
||||||
};
|
};
|
||||||
|
|
||||||
void setOperationPhase(CompilationPhase phase);
|
void setOperationPhase(CompilationPhase phase);
|
||||||
|
|
Loading…
Reference in New Issue