Skip to content

Commit

Permalink
增加了CreateVariable
Browse files Browse the repository at this point in the history
  • Loading branch information
wangziwenhk committed Sep 29, 2024
1 parent 1f9534e commit 7b6e7c3
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 96 deletions.
21 changes: 21 additions & 0 deletions src/IR/Builder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module;
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Value.h>
module IR.Builder;
import Type.Variable;
namespace Riddle {
llvm::Value *Builder::CreateVariable(llvm::Type *type, llvm::Value *value, const std::string &name, const bool is_const){
llvm::Value *var;
// 对全局变量特判
if(ctx->deep() <= 1) {
llvm::Constant *CV = llvm::dyn_cast<llvm::Constant>(value);
var = new llvm::GlobalVariable(ctx->module, type, is_const, llvm::GlobalVariable::LinkageTypes::ExternalLinkage, CV, name);
} else {
var = llvmBuilder.CreateAlloca(type, nullptr, name);
llvmBuilder.CreateStore(value, var);
}
ctx->addVariable(Variable(name,var,is_const));
return var;
}

}
40 changes: 34 additions & 6 deletions src/IR/Builder.ixx
Original file line number Diff line number Diff line change
@@ -1,14 +1,42 @@
module;
#include "llvm/IR/Module.h"
export module Builder;
#include <llvm/IR/IRBuilder.h>
export module IR.Builder;

import IR.Context;

export namespace Riddle {
class Builder {
Context *ctx = nullptr;
llvm::IRBuilder<> llvmBuilder;

public:
llvm::Module &module;
llvm::LLVMContext &context;
explicit Builder(Context &context): ctx(&context), llvmBuilder(ctx->context) {}

/// @brief 获取不同位数的整数类型
/// @param bits 整数类型的位数
/// @return llvm:IntegerTy
inline llvm::Type *getIntegerTy(const unsigned bits = 32) const {
return llvm::Type::getIntNTy(ctx->context, bits);
}

inline llvm::Type *getFloatTy() const {
return llvm::Type::getFloatTy(ctx->context);
}

inline llvm::Type *getDoubleTy() const {
return llvm::Type::getDoubleTy(ctx->context);
}

inline llvm::Type *getVoidTy() const {
return llvm::Type::getVoidTy(ctx->context);
}

inline llvm::Type *getBoolTy() const {
return getIntegerTy(1);
}

llvm::Value *CreateVariable(llvm::Type *type, llvm::Value *value, const std::string &name = "", bool is_const = false);

explicit Builder(llvm::Module &module): module(module), context(module.getContext()) {}


};
}// namespace Riddle
35 changes: 35 additions & 0 deletions src/IR/Context.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module;
#include <stdexcept>
module IR.Context;

namespace Riddle {
Variable &VarManager::getVariable(const std::string &name) {
if(!Vars.contains(name) || Vars.find(name)->second.empty()) {
throw std::logic_error("Variable not found");
}
return *Vars[name].top();
}

void VarManager::addVariable(Variable &var) {
if(Defined.top().contains(var.name)) {
throw std::logic_error("Variable already exists");
}
Defined.top().insert(var.name);
Vars[var.name].push(&var);
}

void VarManager::push() {
Defined.emplace();
}

void VarManager::pop() {
for(const auto &i: Defined.top()) {
Vars[i].pop();
if(Vars[i].empty()) {
Vars.erase(i);
}
}
Defined.pop();
}

}// namespace Riddle
78 changes: 47 additions & 31 deletions src/IR/Context.ixx
Original file line number Diff line number Diff line change
@@ -1,63 +1,79 @@
module;
#include "llvm/IR/LLVMContext.h"

#include "llvm/IR/Module.h"
#include "llvm/Linker/Linker.h"
#include <stack>
#include <unordered_map>
#include <unordered_set>
export module Context;
export module IR.Context;

import Type.Variable;
import Types.UnionFind;

namespace Riddle {
class VarManager {
std::unordered_map<std::string, std::stack<Variable *>> Vars;
std::stack<std::unordered_set<std::string>> Defined;
std::stack<std::unordered_set<std::string>> Defined = {};

public:
VarManager(): Vars({}) {}

/// @brief 获取一个变量
Variable &getVariable(const std::string &name) {
if(!Vars.contains(name) || Vars.find(name)->second.empty()) {
throw std::out_of_range("Variable not found");
}
return *Vars[name].top();
}
/// @param name 变量名
/// @return 变量
Variable &getVariable(const std::string &name);

void addVariable(Variable &var) {
if(Defined.top().contains(var.name)) {
throw std::logic_error("Variable already exists");
}
Defined.top().insert(var.name);
Vars[var.name].push(&var);
}
/// @brief 添加一个变量
/// @param var 变量
void addVariable(Variable &var);

void push() {
Defined.emplace();
}
/// @brief 进入下一个生命周期
void push();

void pop() {
for(auto i: Defined.top()) {
Vars[i].pop();
if(Vars[i].empty()) {
Vars.erase(i);
}
}
Defined.pop();
}
/// @brief 退出当前作用域
void pop();
};
}// namespace Riddle

export namespace Riddle {
class Context {
int _deep = 0;

public:
llvm::LLVMContext &context;
llvm::Module module;
VarManager varManager;

explicit Context(llvm::LLVMContext &context): context(context) {}
explicit Context(llvm::LLVMContext &context): context(context), module("", context) {}

void addVar(Variable var) {
inline void addVariable(Variable var) {
varManager.addVariable(var);
}

inline void push() {
varManager.push();
}

inline void pop() {
varManager.pop();
}

inline unsigned long long deep() const {
return _deep;
}

void merge(const Context &ctx) {
llvm::Linker linker(module);
auto t = std::make_unique<llvm::Module>(ctx.module.getModuleIdentifier(), ctx.context);

// 复制源模块的布局和目标配置
t->setDataLayout(ctx.module.getDataLayout());
t->setTargetTriple(ctx.module.getTargetTriple());

if(linker.linkInModule(std::move(t))) {
llvm::errs() << "Error: Failed to merge modules.\n";
} else {
llvm::outs() << "Modules merged successfully.\n";
}
}
};
}
54 changes: 0 additions & 54 deletions src/Types/UnionFind.ixx

This file was deleted.

2 changes: 1 addition & 1 deletion src/Types/Unit.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export namespace Riddle {
void addImports(const std::string &lib);
void addImports(const std::vector<std::string> &libs);
[[nodiscard]] std::vector<std::string> getImports() const;
size_t getImportSize()const;
[[nodiscard]] size_t getImportSize()const;
/// @brief 添加优先级比较
bool operator>(const Unit &x)const;
bool operator<(const Unit &x)const;
Expand Down
6 changes: 3 additions & 3 deletions src/Types/Variable.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ export namespace Riddle {
class Variable {
public:
const std::string name;
llvm::Value *value;
llvm::Value *var;
const bool isConst;
Variable() = delete;
Variable(std::string name,
llvm::Value *value,
const bool isConst = false): name(std::move(name)), value(value), isConst(isConst){};
llvm::Value *var,
const bool isConst = false): name(std::move(name)), var(var), isConst(isConst){};
};

}// namespace Riddle
2 changes: 1 addition & 1 deletion src/Visitors/GenVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace Riddle {
}

std::any GenVisitor::visitObjectExpr(RiddleParser::ObjectExprContext *ctx) {
llvm::Value *value = varManager.getVar(ctx->Identifier()->getText()).value;
llvm::Value *value = varManager.getVar(ctx->Identifier()->getText()).var;
return std::tuple{value, value->getType()};
}

Expand Down

0 comments on commit 7b6e7c3

Please sign in to comment.