Port to LLVM 14.
This commit is contained in:
parent
097a6fc511
commit
2f91c61296
|
@ -2,7 +2,7 @@
|
||||||
# Use of this source code is governed by a GPLv3 license, see LICENSE.txt.
|
# Use of this source code is governed by a GPLv3 license, see LICENSE.txt.
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.7)
|
cmake_minimum_required(VERSION 3.7)
|
||||||
project(Monicelli VERSION 2.0.0 LANGUAGES CXX)
|
project(Monicelli VERSION 2.1.0 LANGUAGES C CXX)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
|
|
@ -49,11 +49,11 @@ you will need to have installed. If this is not the case, the configuration
|
||||||
script will warn you. Monicelli is developed with version 6.8, but any
|
script will warn you. Monicelli is developed with version 6.8, but any
|
||||||
sufficiently recent release should do just fine.
|
sufficiently recent release should do just fine.
|
||||||
|
|
||||||
You will also need to have LLVM development libraries installed, version 7, 8 or 9.
|
You will also need to have LLVM development libraries installed, version 14.
|
||||||
Other versions might or might not work. CMake looks for version 7 by default, you
|
Newer versions might or might not work. CMake looks for version 14 by default, you
|
||||||
can override this by setting the `MONICELLI_LLVM_VERSION` variable:
|
can override this by setting the `MONICELLI_LLVM_VERSION` variable:
|
||||||
|
|
||||||
$ cmake -DMONICELLI_LLVM_VERSION=9
|
$ cmake -DMONICELLI_LLVM_VERSION=15
|
||||||
|
|
||||||
Finally, you will need CMake, version 3.7 or higher.
|
Finally, you will need CMake, version 3.7 or higher.
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# Use of this source code is governed by a GPLv3 license, see LICENSE.txt.
|
# Use of this source code is governed by a GPLv3 license, see LICENSE.txt.
|
||||||
|
|
||||||
set(MONICELLI_ARCH "x86" CACHE STRING "Target architecture for Monicelli.")
|
set(MONICELLI_ARCH "x86" CACHE STRING "Target architecture for Monicelli.")
|
||||||
set(MONICELLI_LLVM_VERSION 7 CACHE STRING "LLVM version for Monicelli.")
|
set(MONICELLI_LLVM_VERSION 14 CACHE STRING "LLVM version for Monicelli.")
|
||||||
set(MONICELLI_LINKER ON CACHE BOOL "Enable the Monicelli linker. Requires POSIX.")
|
set(MONICELLI_LINKER ON CACHE BOOL "Enable the Monicelli linker. Requires POSIX.")
|
||||||
|
|
||||||
find_package(LLVM "${MONICELLI_LLVM_VERSION}" REQUIRED CONFIG)
|
find_package(LLVM "${MONICELLI_LLVM_VERSION}" REQUIRED CONFIG)
|
||||||
|
@ -36,7 +36,7 @@ add_executable(mcc
|
||||||
|
|
||||||
set_target_properties(mcc lexer
|
set_target_properties(mcc lexer
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
CXX_STANDARD 11
|
CXX_STANDARD 14
|
||||||
CXX_STANDARD_REQUIRED true
|
CXX_STANDARD_REQUIRED true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,9 @@
|
||||||
|
|
||||||
#include "llvm/IR/LegacyPassManager.h"
|
#include "llvm/IR/LegacyPassManager.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/MC/TargetRegistry.h"
|
||||||
|
#include "llvm/Support/CodeGen.h"
|
||||||
#include "llvm/Support/FileSystem.h"
|
#include "llvm/Support/FileSystem.h"
|
||||||
#include "llvm/Support/TargetRegistry.h"
|
|
||||||
#include "llvm/Support/TargetSelect.h"
|
#include "llvm/Support/TargetSelect.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ llvm::TargetMachine* getTargetMachine(const std::string& triple, const std::stri
|
||||||
void writeAssembly(const std::string& to_filename, llvm::Module* module,
|
void writeAssembly(const std::string& to_filename, llvm::Module* module,
|
||||||
llvm::TargetMachine* target_machine) {
|
llvm::TargetMachine* target_machine) {
|
||||||
std::error_code error_code;
|
std::error_code error_code;
|
||||||
llvm::raw_fd_ostream output{to_filename, error_code, llvm::sys::fs::F_None};
|
llvm::raw_fd_ostream output{to_filename, error_code, llvm::sys::fs::OF_None};
|
||||||
|
|
||||||
if (error_code) {
|
if (error_code) {
|
||||||
std::cerr << "Could not open '" << to_filename << "' for output: " << error_code.message()
|
std::cerr << "Could not open '" << to_filename << "' for output: " << error_code.message()
|
||||||
|
@ -56,7 +57,7 @@ void writeAssembly(const std::string& to_filename, llvm::Module* module,
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::legacy::PassManager asm_generator;
|
llvm::legacy::PassManager asm_generator;
|
||||||
auto file_type = llvm::TargetMachine::CGFT_ObjectFile;
|
auto file_type = llvm::CGFT_ObjectFile;
|
||||||
|
|
||||||
if (target_machine->addPassesToEmitFile(asm_generator, output, nullptr, file_type)) {
|
if (target_machine->addPassesToEmitFile(asm_generator, output, nullptr, file_type)) {
|
||||||
std::cerr << "Cannot emit an object file of this type\n";
|
std::cerr << "Cannot emit an object file of this type\n";
|
||||||
|
|
|
@ -16,12 +16,14 @@
|
||||||
#include "llvm/IR/LegacyPassManager.h"
|
#include "llvm/IR/LegacyPassManager.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/IR/Verifier.h"
|
#include "llvm/IR/Verifier.h"
|
||||||
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/raw_os_ostream.h"
|
#include "llvm/Support/raw_os_ostream.h"
|
||||||
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
#include "llvm/Transforms/Scalar.h"
|
||||||
#include "llvm/Transforms/Scalar/GVN.h"
|
#include "llvm/Transforms/Scalar/GVN.h"
|
||||||
#include "llvm/Transforms/Utils.h"
|
#include "llvm/Transforms/Utils.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace monicelli;
|
using namespace monicelli;
|
||||||
|
@ -170,19 +172,19 @@ llvm::Value* NestedScopes::lookup(const std::string& name) {
|
||||||
|
|
||||||
void IRGenerator::declareBuiltins() {
|
void IRGenerator::declareBuiltins() {
|
||||||
llvm::FunctionType* abort_type = llvm::FunctionType::get(builder_.getVoidTy(), false);
|
llvm::FunctionType* abort_type = llvm::FunctionType::get(builder_.getVoidTy(), false);
|
||||||
auto no_return = llvm::AttributeList().addAttribute(context_, 1, llvm::Attribute::NoReturn);
|
auto no_return = llvm::AttributeList().addFnAttribute(context_, llvm::Attribute::NoReturn);
|
||||||
module_->getOrInsertFunction("abort", abort_type, no_return);
|
module_->getOrInsertFunction("abort", abort_type, no_return);
|
||||||
|
|
||||||
llvm::FunctionType* printf_type =
|
llvm::FunctionType* printf_type =
|
||||||
llvm::FunctionType::get(builder_.getInt32Ty(), {builder_.getInt8PtrTy()}, true);
|
llvm::FunctionType::get(builder_.getInt32Ty(), {builder_.getInt8PtrTy()}, true);
|
||||||
auto no_alias = llvm::AttributeList().addAttribute(context_, 1, llvm::Attribute::NoAlias);
|
auto no_alias = llvm::AttributeList().addParamAttribute(context_, 0, llvm::Attribute::NoAlias);
|
||||||
|
|
||||||
module_->getOrInsertFunction("printf", printf_type, no_alias);
|
module_->getOrInsertFunction("printf", printf_type, no_alias);
|
||||||
module_->getOrInsertFunction("scanf", printf_type, no_alias);
|
module_->getOrInsertFunction("scanf", printf_type, no_alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value* IRGenerator::visitModule(const Module* m) {
|
llvm::Value* IRGenerator::visitModule(const Module* m) {
|
||||||
module_ = llvm::make_unique<llvm::Module>("antani", context_);
|
module_ = std::make_unique<llvm::Module>("antani", context_);
|
||||||
|
|
||||||
declareBuiltins();
|
declareBuiltins();
|
||||||
|
|
||||||
|
@ -245,7 +247,7 @@ llvm::Value* IRGenerator::visitFunction(const Function* ast_f) {
|
||||||
for (auto& arg : f->args()) {
|
for (auto& arg : f->args()) {
|
||||||
auto arg_ptr = builder_.CreateAlloca(arg.getType(), nullptr, arg.getName());
|
auto arg_ptr = builder_.CreateAlloca(arg.getType(), nullptr, arg.getName());
|
||||||
builder_.CreateStore(&arg, arg_ptr);
|
builder_.CreateStore(&arg, arg_ptr);
|
||||||
var_scopes_.define(arg.getName(), arg_ptr);
|
var_scopes_.define(arg.getName().str(), arg_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_block_ = llvm::BasicBlock::Create(context_, "exit");
|
exit_block_ = llvm::BasicBlock::Create(context_, "exit");
|
||||||
|
@ -260,7 +262,7 @@ llvm::Value* IRGenerator::visitFunction(const Function* ast_f) {
|
||||||
builder_.SetInsertPoint(exit_block_);
|
builder_.SetInsertPoint(exit_block_);
|
||||||
|
|
||||||
if (return_var_) {
|
if (return_var_) {
|
||||||
builder_.CreateRet(builder_.CreateLoad(return_var_));
|
builder_.CreateRet(builder_.CreateLoad(f->getReturnType(), return_var_));
|
||||||
} else {
|
} else {
|
||||||
builder_.CreateRetVoid();
|
builder_.CreateRetVoid();
|
||||||
}
|
}
|
||||||
|
@ -518,7 +520,7 @@ llvm::Value* IRGenerator::visitInputStatement(const InputStatement* s) {
|
||||||
callIOBuiltin<false>(target_type, target);
|
callIOBuiltin<false>(target_type, target);
|
||||||
|
|
||||||
if (reading_bool) {
|
if (reading_bool) {
|
||||||
builder_.CreateStore(evalTruthiness(builder_.CreateLoad(target)), var);
|
builder_.CreateStore(evalTruthiness(builder_.CreateLoad(target_type, target)), var);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -638,12 +640,12 @@ llvm::Value* IRGenerator::visitAtomicExpression(const AtomicExpression* e) {
|
||||||
case AtomicExpression::FLOAT:
|
case AtomicExpression::FLOAT:
|
||||||
return llvm::ConstantFP::get(builder_.getDoubleTy(), e->getFloatValue());
|
return llvm::ConstantFP::get(builder_.getDoubleTy(), e->getFloatValue());
|
||||||
case AtomicExpression::IDENTIFIER: {
|
case AtomicExpression::IDENTIFIER: {
|
||||||
auto var = var_scopes_.lookup(e->getIdentifierValue().getName());
|
auto var =
|
||||||
|
llvm::cast_or_null<llvm::AllocaInst>(var_scopes_.lookup(e->getIdentifierValue().getName()));
|
||||||
if (!var) {
|
if (!var) {
|
||||||
error(&e->getIdentifierValue(), "undefined variable", e->getIdentifierValue().getName());
|
error(&e->getIdentifierValue(), "undefined variable", e->getIdentifierValue().getName());
|
||||||
}
|
}
|
||||||
assert(llvm::isa<llvm::AllocaInst>(var));
|
return builder_.CreateLoad(var->getAllocatedType(), var);
|
||||||
return builder_.CreateLoad(var);
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
UNREACHABLE("Unhandled AtomicExpression type");
|
UNREACHABLE("Unhandled AtomicExpression type");
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
|
||||||
|
#include "llvm/Support/Host.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
Reference in New Issue
Block a user