fix(frontend): 移除前端对全局变量的支持

master
李仁哲 1 month ago
parent 2c8a64c763
commit e104a3d546

@ -80,7 +80,7 @@
// 编译单元
CompUnit ::= { GlobalItem }
GlobalItem ::= Decl | FuncDef
GlobalItem ::= FuncDef
// 声明
Decl ::= VarDecl

@ -61,7 +61,6 @@ impl Display for VReg {
let mut asm = String::new();
let str = match self.1 {
RegKind::Integer => "vw",
_ => "invalid",
};
asm += str.to_string().as_str();
asm += &self.0.to_string();

@ -1,10 +1,8 @@
use std::collections::BTreeSet;
use std::hash::Hash;
use super::{mir_label::MirLabel,
mir_block::MirBlock,
mir_context::MirContext,
regs::PReg};
mir_context::MirContext};
use crate::utils::{linked_list::LinkedListContainer,
storage::{Arena, ArenaPtr, GenericPtr}};

@ -5,7 +5,7 @@ use super::{
mir_operand::MemLoc,
regs::Reg,
};
use crate::{ backend::mir::mir_label::MirLabel, utils::{
use crate::{ utils::{
linked_list::{LinkedListContainer, LinkedListError, LinkedListNode},
storage::{Arena, ArenaPtr, GenericPtr},
}};

@ -40,8 +40,6 @@ impl PartialEq for Reg {
match (a.kind(), b.kind()) {
// 通用寄存器文件Integer共享
(RegKind::Integer, RegKind::Integer) => a.0 == b.0,
// 不同寄存器文件(通用 vs 浮点)
_ => false,
}
}
@ -86,7 +84,6 @@ impl PReg {
pub const fn is_integer(&self) -> bool {
match self.1 {
RegKind::Integer => true,
_ => false,
}
}
pub fn hw_index(&self) -> u8 { self.0}

@ -1,7 +1,7 @@
use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet};
use rustc_hash::{FxHashMap as HashMap};
use super::mir::{
mir_block::MirBlock,
mir_context::{MirContext,RawData},
mir_context::{MirContext},
mir_function::MirFunction,
mir_inst::{MirInst},
mir_label::MirLabel,
@ -10,7 +10,7 @@ use super::mir::{
};
use crate::{
frontend::ir::{
self, basicblock::BasicBlock,function::Function, global::GlobalData, instruction::{InstructionKind, MemAccessOp}, value::{ConstantValue, Value}
self, basicblock::BasicBlock,function::Function, instruction::{ MemAccessOp}, value::{ConstantValue, Value}
}, utils::{
linked_list::{LinkedListContainer},
storage::ArenaPtr,
@ -33,20 +33,6 @@ pub trait MirGen {
fn mirgen(&self, mirgen: &mut MirgenContext);
}
impl MirGen for GlobalData {
fn mirgen(&self, mirgen: &mut MirgenContext) {
let global = self.self_ptr;
let name = global.name(mirgen.ctx).to_string();
let label_name = name.trim_start_matches('@').to_string();
let label = MirLabel::from(label_name.clone());
mirgen.globals.insert(name.clone(), label.clone());
match global.value(mirgen.ctx) {
_ => todo!(),
}
}
}
impl MirGen for ir::function::Function {
fn mirgen(&self, mirgen: &mut MirgenContext) {
let name = self.get_id(mirgen.ctx);
@ -90,7 +76,6 @@ impl MirGen for ir::instruction::Instruction {
}
}
},
_ => todo!(),
}
}
ir::instruction::InstructionKind::Binary { op } => {
@ -105,7 +90,6 @@ impl MirGen for ir::instruction::Instruction {
let add = MirInst::add(&mut mirgen.mctx, temp_reg, lhs_reg, rhs_reg);
let _ = mirgen.curr_block.as_ref().unwrap().push_back(&mut mirgen.mctx, add);
}
_ => todo!("Unsupported binary operation: {:?}", op),
}
mirgen.table.insert(result_val, MirOperand {
typ: result_val.kind(mirgen.ctx),
@ -216,9 +200,6 @@ impl<'s> MirgenContext<'s> {
pub fn mircontext(self) -> MirContext { self.mctx }
pub fn mirgen(&mut self) {
for global_data in self.ctx.globals.iter() {
global_data.mirgen(self);
}
for func in self.ctx.get_functions() {
func.mirgen(self);
@ -289,12 +270,8 @@ impl<'s> MirgenContext<'s> {
}
}
pub fn generate_ret_reg(&mut self, ty: ir::typ::Typ) -> PReg {
if ty.is_ptr(self.ctx) {
todo!()
} else {
regs::w0().into()
}
pub fn generate_ret_reg(&mut self, _ty: ir::typ::Typ) -> PReg {
regs::w0().into()
}
pub fn generate_opd_reg(&mut self, opd: ir::value::Value) -> Reg {

@ -4,7 +4,6 @@ use crate::{backend::mir::{
mir_context::MirContext,
mir_function::MirFunction,
mir_inst::MirInst,
mir_operand::MemLoc,
regs::{self, Reg},
}, utils::linked_list::{LinkedListContainer, LinkedListNode}};

@ -1,6 +1,5 @@
use super::basicblock::{BasicBlock, BasicBlockData};
use super::function::{Function, FunctionData};
use super::global::{Global, GlobalData};
use super::instruction::{Instruction, InstructionData};
use super::typ::{Typ, TypeData};
use super::value::{Value, ValueData};
@ -9,7 +8,6 @@ use crate::utils::storage::{Arena, GenericArena, GenericPtr, UniqueArena};
pub struct Context {
pub target: usize,
pub types: UniqueArena<TypeData>,
pub globals: GenericArena<GlobalData>,
pub values: GenericArena<ValueData>,
pub basicblocks: GenericArena<BasicBlockData>,
pub functions: GenericArena<FunctionData>,
@ -28,7 +26,6 @@ impl Context {
Self {
target: target,
types: UniqueArena::default(),
globals: GenericArena::default(),
values: GenericArena::default(),
basicblocks: GenericArena::default(),
functions: GenericArena::default(),
@ -75,34 +72,6 @@ impl Arena<Typ> for Context {
}
}
impl Arena<Global> for Context {
fn alloc_with<F>(&mut self, f: F) -> Global
where
F: FnOnce(Global) -> GlobalData,
{
Global(
self.globals
.alloc_with(|ptr: GenericPtr<GlobalData>| f(Global(ptr))),
)
}
fn alloc(&mut self, data: GlobalData) -> Global {
Global(self.globals.alloc_with(|_| data))
}
fn dealloc(&mut self, ptr: Global) -> Option<GlobalData> {
self.globals.dealloc(ptr.0)
}
fn deref(&self, ptr: Global) -> Option<&GlobalData> {
self.globals.deref(ptr.0)
}
fn deref_mut(&mut self, ptr: Global) -> Option<&mut GlobalData> {
self.globals.deref_mut(ptr.0)
}
}
impl Arena<Value> for Context {
/// 申请一个新的值并用f初始化该值f是一个函数闭包闭包要求传入一个Value作为参数并返回一个ValueData
fn alloc_with<F>(&mut self, f: F) -> Value

@ -1,56 +0,0 @@
use super::context::Context;
use super::typ::Typ;
use super::value::ConstantValue;
use crate::utils::storage::{Arena, ArenaPtr, GenericPtr};
pub struct GlobalData {
pub self_ptr: Global,
name: String,
value: ConstantValue,
}
impl GlobalData {
pub fn get_self_ptr(&self) -> Global {
self.self_ptr
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Copy)]
pub struct Global(pub GenericPtr<GlobalData>);
impl ArenaPtr for Global {
type Arena = Context;
type Data = GlobalData;
}
impl Global {
/// 创建一个全局变量
pub fn new(ctx: &mut Context, name: String, value: ConstantValue) -> Self {
ctx.alloc_with(|self_ptr| GlobalData {
self_ptr,
name,
value,
})
}
/// 获取全局变量的名称
pub fn name(self, ctx: &Context) -> &str {
&self
.deref(ctx)
.expect("Failed to deref `name` of struct Global")
.name
}
/// 获取全局变量的值
pub fn value(self, ctx: &Context) -> &ConstantValue {
&self
.deref(ctx)
.expect("Failed to deref `value` of struct Global")
.value
}
/// 获取全局变量的类型
pub fn typ(self, ctx: &Context) -> Typ {
self.value(ctx).typ()
}
}

@ -1,6 +1,5 @@
pub mod context;
pub mod typ;
pub mod global;
pub mod value;
pub mod function;
pub mod basicblock;

@ -7,7 +7,6 @@ use crate::{
pub enum TypeData {
Void,
Int32,
Ptr { typ_of_ptr: Typ },
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, Copy, PartialOrd)]
@ -35,21 +34,12 @@ impl Typ {
pub fn is_int32(&self, ctx: &Context) -> bool {
matches!(self.deref(ctx).unwrap(), TypeData::Int32)
}
pub fn ptr(ctx: &mut Context, typ_of_ptr: Typ) -> Self {
ctx.alloc(TypeData::Ptr { typ_of_ptr })
}
pub fn is_ptr(&self, ctx: &Context) -> bool {
matches!(self.deref(ctx).unwrap(), TypeData::Ptr { .. })
}
/// 类型所占位数
pub fn bitwidth(&self, ctx: &Context) -> usize {
match self.deref(ctx).unwrap() {
TypeData::Void => 0,
TypeData::Int32 => 32,
TypeData::Ptr { .. } => ctx.target as usize * 8,
}
}

@ -18,11 +18,6 @@ pub enum ConstantValue {
typ: Typ,
value: i32,
},
GlobalPtr {
typ: Typ, // 全局指针类型
name: String, // 全局变量的名
value_type: Typ, // 指针指向数据的类型
},
}
impl ConstantValue {
@ -32,7 +27,6 @@ impl ConstantValue {
ConstantValue::Undef { typ } => *typ,
ConstantValue::Zero { typ, .. } => *typ,
ConstantValue::Int32 { typ, .. } => *typ,
ConstantValue::GlobalPtr { value_type, .. } => *value_type,
}
}
@ -59,15 +53,6 @@ impl ConstantValue {
ConstantValue::Int32 { typ: int32, value }
}
pub fn global_ptr(ctx: &mut Context, name: String, value_type: Typ) -> ConstantValue {
let global_ptr = Typ::ptr(ctx, value_type.clone());
ConstantValue::GlobalPtr {
typ: global_ptr,
name,
value_type,
}
}
pub fn to_string(&self, _ctx: &Context) -> String {
let mut str = String::new();
@ -77,10 +62,6 @@ impl ConstantValue {
str.push_str("0")
}
ConstantValue::Int32 { value, .. } => str.push_str(&value.to_string()),
ConstantValue::GlobalPtr { name, .. } => {
str.push_str("@");
str.push_str(name);
}
}
str
}
@ -199,23 +180,6 @@ impl Value {
ValueKind::Constant { .. }
)
}
pub fn global_ptr(ctx: &mut Context, name: String, value_type: Typ) -> Self {
let t = ConstantValue::global_ptr(ctx, name, value_type);
let t = Self::new(ctx, ValueKind::Constant { value: t });
t
}
pub fn is_global_ptr(&self, ctx: &Context) -> bool {
matches!(
self.deref(ctx)
.expect("Failed to deref `is_global_ptr` in Value")
.kind,
ValueKind::Constant {
value: ConstantValue::GlobalPtr { .. }
}
)
}
}
impl Useable for Value {

@ -2,7 +2,6 @@ use super::ir::{
basicblock::BasicBlock,
context::Context,
function::Function,
global::{Global, GlobalData},
instruction::{
BinaryOp as IBinaryOp,InstructionKind,
MemAccessOp, TerminatorOp
@ -25,13 +24,6 @@ pub trait Display {
impl Context {
pub fn get_ir_string(&self) -> String {
let mut ir = String::new();
for GlobalData {
self_ptr: global, ..
} in self.globals.iter()
{
ir += &format!("{}\n", global.display(self));
}
for func in self.get_functions() {
ir += &format!("{}\n", func.display(self));
}
@ -39,24 +31,6 @@ impl Context {
}
}
impl Display for Global {
fn display(self, ctx: &Context) -> String {
let mut ir = String::new();
let typ = self.value(ctx).typ().display(ctx);
if self.value(ctx).is_undef() || self.value(ctx).is_zero() {
ir += &format!("@{} = global {} zeroinitializer\n", self.name(ctx), typ);
} else {
ir += &format!(
"@{} = global {} {}\n",
self.name(ctx),
typ,
self.value(ctx).to_string(ctx)
);
}
ir
}
}
impl Display for Function {
fn display(self, ctx: &Context) -> String {
let mut ir = String::new();
@ -95,13 +69,6 @@ impl Display for Typ {
TypeData::Int32 => {
ir += "i32";
}
TypeData::Ptr { typ_of_ptr: typ } => {
if typ.is_void(ctx) {
ir += &format!("i8*")
} else {
ir += &format!("{}*", typ.display(ctx));
}
}
}
ir
}

@ -3,7 +3,6 @@ use super::{
basicblock::BasicBlock,
context::{Context},
function::Function,
global::Global,
instruction::{
BinaryOp as IBinaryOp, Instruction,
MemAccessOp,
@ -24,19 +23,13 @@ use crate::{
#[derive(Debug, Clone, Copy)]
pub enum IrGenResult {
Global(Global), //全局变量需要特殊处理和一般的值不同需要通过地址访问
Value(Value),
}
impl IrGenResult {
pub fn unwrap(self, ctx: &mut Context) -> Value {
pub fn unwrap(self, _ctx: &mut Context) -> Value {
match self {
IrGenResult::Value(val) => val,
IrGenResult::Global(slot) => {
let name = slot.name(ctx).to_string();
let value_ty = slot.typ(ctx);
Value::global_ptr(ctx, name, value_ty)
}
}
}
}
@ -71,10 +64,6 @@ impl IrGenContext {
match typ.kind() {
TypeKind::Void => Typ::void(&mut self.ctx),
TypeKind::Int => Typ::int32(&mut self.ctx),
TypeKind::Ptr(ty) => {
let ty = self.ast2ir_type(ty);
Typ::ptr(&mut self.ctx, ty)
}
TypeKind::Function(..) => unreachable!("function type should be handled separately"),
}
}
@ -150,51 +139,6 @@ impl IrGenContext {
}
}
}
// /// 将AST中的函数参数转化为IR中的函数参数过程和表达式计算不相同尤其是在数组和指针的处理上
// fn ast2ir_param(&mut self, exp: &Exp, _param_type: Typ) -> Option<Value> {
// let cur_bbk = self.cur_bbk.unwrap();
// match &exp.kind {
// ExpKind::Const(v) => {
// let value_of_ir = self.ast2ir_const(v);
// Some(Value::constant(&mut self.ctx, value_of_ir))
// }
// ExpKind::Binary(..) => self.ast2ir_binary(exp),
// ExpKind::LVal(LVal { id }) => {
// //在符号表中查找变量的IR值
// let entry = self.symboltable.lookup(id).unwrap();
// let ir_value = entry.ir_value.unwrap();
// //获取变量类型
// let typ_of_ir = self.ast2ir_type(&entry.typ.clone());
// let slot = ir_value.unwrap(&mut self.ctx);
// if slot.is_parameter(&self.ctx){
// //如果时函数参数直接返回slot因为此时的值已经在栈帧中
// Some(slot)
// } else {
// //不是函数参数则可能是临时变量或者全局变量,需要从内存中加载出来
// let instruction = Instruction::memaccess(
// &mut self.ctx,
// MemAccessOp::Load,
// typ_of_ir,
// vec![slot],
// );
// cur_bbk.push_back(&mut self.ctx, instruction).unwrap();
// Some(
// instruction
// .get_result(&self.ctx)
// .expect("Failed to unwrap the result of the lval in AST"),
// )
// }
// }
// }
// }
fn bbk_end_with_terminator(&mut self) -> bool {
let cur_bbk = self.cur_bbk.as_ref().unwrap();
// Check if the current basic block ends with a terminator instruction
cur_bbk.is_terminated(&self.ctx)
}
}
pub trait IrGen {
@ -218,36 +162,6 @@ impl IrGen for GlobalItem {
// Generate IR for an item.
fn irgen(&self, irgen: &mut IrGenContext) {
match self {
GlobalItem::Decl(decl) => match decl {
Decl::VarDecl(VarDecl { defs, .. }) => {
for VarDef { id, init, .. } in defs {
// 未给出初始化值的变量声明默认初始化为0
let init = init.as_ref().unwrap();
let comptime = match init {
InitVal::Exp(exp) => exp
.try_fold(&irgen.symboltable)
.expect("global def expected to have constant initializer"),
};
let constant = irgen.ast2ir_const(&comptime);
let slot = Global::new(
&mut irgen.ctx,
format!("NUDT_GLOBAL_VAR_{}", id),
constant,
);
irgen.symboltable.insert(
id.clone(),
SymbolEntry {
typ: match init {
InitVal::Exp(exp) => exp.typ().clone(),
},
comptime: Some(comptime),
ir_value: Some(IrGenResult::Global(slot)),
},
);
}
}
},
GlobalItem::FuncDef(func_def) => func_def.irgen(irgen),
}
}
@ -373,7 +287,7 @@ impl IrGen for FuncDef {
// 为函数添加返回基本块(保证每个函数的出口唯一)
function.push_back(&mut irgen.ctx, ret_block).unwrap();
if !irgen.bbk_end_with_terminator() {
if !irgen.cur_bbk.unwrap().is_terminated(&irgen.ctx) {
// 有可能函数在之前就已经有ret指令
let br2ret = Instruction::br(&mut irgen.ctx, ret_block);
irgen

@ -4,7 +4,7 @@ use std::collections::HashMap;
use std::rc::Rc;
use std::{fmt, hash};
// CompUnit -> [CompUnit](Decl|FuncDef)
// CompUnit -> [CompUnit](FuncDef)
#[derive(Debug)]
pub struct CompUnit {
pub items: Vec<GlobalItem>,
@ -12,7 +12,6 @@ pub struct CompUnit {
#[derive(Debug)]
pub enum GlobalItem {
Decl(Decl),
FuncDef(FuncDef),
}
@ -160,7 +159,6 @@ pub enum BinaryOp {
#[derive(Debug, Clone)]
pub enum ComptimeValue {
Int(i32),
Undef(Type),
}
@ -237,7 +235,6 @@ impl Eq for ComptimeValue {}
pub enum TypeKind {
Void,
Int,
Ptr(Box<Type>),
Function(Vec<Type>, Box<Type>),
}
@ -269,7 +266,6 @@ impl fmt::Display for Type {
match self.kind() {
TypeKind::Void => write!(f, "void"),
TypeKind::Int => write!(f, "int"),
TypeKind::Ptr(t) => write!(f, "{}*", t),
TypeKind::Function(params, ret) => write!(
f,
"{}({})",

@ -24,11 +24,10 @@ pub Number: ComptimeValue = {
}
// Nonterminal symbols definition
// CompUnit -> [CompUnit](Decl|FuncDef)
// CompUnit -> [CompUnit](FuncDef)
pub CompUnit: CompUnit = <items: (GlobalItem)*> => CompUnit{ <> };
GlobalItem: GlobalItem = {
Decl => GlobalItem::Decl(<>),
FuncDef => GlobalItem::FuncDef(<>),
}

@ -22,9 +22,6 @@ impl CompUnit {
impl GlobalItem {
pub fn type_check(&mut self, symtable: &mut SymbolTable) {
match self {
GlobalItem::Decl(decl) => match decl {
Decl::VarDecl(decl) => decl.type_check(symtable),
},
GlobalItem::FuncDef(FuncDef {
typ,
id,

Binary file not shown.

@ -0,0 +1,16 @@
define i32 @main() {
bb_0:
%v3 = alloca i32
%v1 = alloca i32
%v0 = alloca i32
store i32 1, i32* %v1
store i32 2, i32* %v3
%v5 = load i32, i32* %v1
%v6 = load i32, i32* %v3
%v7 = add i32 %v5, %v6
store i32 %v7, i32* %v0
br label %bb_1
bb_1:
%v8 = load i32, i32* %v0
ret i32 %v8
}

@ -0,0 +1,23 @@
.arch armv8-a
.text
.global main
.type main, %function
.p2align 3
main:
sub sp, sp, #16
movz w13, #1
str w13, [sp, #4]
movz w11, #2
str w11, [sp]
ldr w12, [sp, #4]
ldr w10, [sp]
add w14, w12, w10
str w14, [sp, #8]
b bb_1
bb_1:
ldr w9, [sp, #8]
mov w0, w9
add sp, sp, #16
ret

@ -0,0 +1,97 @@
CompUnit {
items: [
FuncDef(
FuncDef {
typ: Int,
id: "main",
params: [],
block: Block {
items: [
Decl(
VarDecl(
VarDecl {
typ: Int,
defs: [
VarDef {
id: "a",
init: Some(
Exp(
Exp {
kind: Const(
Int(
1,
),
),
typ: Some(
Int,
),
},
),
),
},
],
},
),
),
Decl(
VarDecl(
VarDecl {
typ: Int,
defs: [
VarDef {
id: "b",
init: Some(
Exp(
Exp {
kind: Const(
Int(
2,
),
),
typ: Some(
Int,
),
},
),
),
},
],
},
),
),
Stmt(
Return(
Return {
exp: Some(
Exp {
kind: Binary(
Add,
Exp {
kind: LVal(
LVal {
id: "a",
},
),
typ: None,
},
Exp {
kind: LVal(
LVal {
id: "b",
},
),
typ: None,
},
),
typ: None,
},
),
},
),
),
],
},
},
),
],
}
Loading…
Cancel
Save