Port to LLVM 14.

This commit is contained in:
Stefano Sanfilippo 2023-01-04 19:24:51 +01:00
parent 097a6fc511
commit 2f91c61296
6 changed files with 23 additions and 18 deletions

View File

@ -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")

View File

@ -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.

View File

@ -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
) )

View File

@ -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";

View File

@ -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");

View File

@ -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>