Improve LLVM IR SSA names
This commit is contained in:
parent
71a01dad69
commit
33d5ee03f0
@ -18,9 +18,9 @@ fn main() {
|
|||||||
FunctionFlags::default(),
|
FunctionFlags::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let arg = m_entry.build(Constant(I32(5))).unwrap();
|
let arg = m_entry.build("const", Constant(I32(5))).unwrap();
|
||||||
let fibonacci_call = m_entry
|
let fibonacci_call = m_entry
|
||||||
.build(FunctionCall(fibonacci.value(), vec![arg]))
|
.build("const", FunctionCall(fibonacci.value(), vec![arg]))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
m_entry
|
m_entry
|
||||||
.terminate(TerminatorKind::Ret(fibonacci_call))
|
.terminate(TerminatorKind::Ret(fibonacci_call))
|
||||||
@ -28,10 +28,10 @@ fn main() {
|
|||||||
|
|
||||||
let mut f_entry = fibonacci.block("entry");
|
let mut f_entry = fibonacci.block("entry");
|
||||||
|
|
||||||
let num_3 = f_entry.build(Constant(I32(3))).unwrap();
|
let num_3 = f_entry.build("const", Constant(I32(3))).unwrap();
|
||||||
let param_n = f_entry.build(Param(0)).unwrap();
|
let param_n = f_entry.build("param", Param(0)).unwrap();
|
||||||
let cond = f_entry
|
let cond = f_entry
|
||||||
.build(ICmp(CmpPredicate::LT, param_n, num_3))
|
.build("cmp", ICmp(CmpPredicate::LT, param_n, num_3))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut then_b = fibonacci.block("then");
|
let mut then_b = fibonacci.block("then");
|
||||||
@ -41,21 +41,21 @@ fn main() {
|
|||||||
.terminate(TerminatorKind::CondBr(cond, then_b.value(), else_b.value()))
|
.terminate(TerminatorKind::CondBr(cond, then_b.value(), else_b.value()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let ret_const = then_b.build(Constant(I32(1))).unwrap();
|
let ret_const = then_b.build("const", Constant(I32(1))).unwrap();
|
||||||
then_b.terminate(TerminatorKind::Ret(ret_const)).unwrap();
|
then_b.terminate(TerminatorKind::Ret(ret_const)).unwrap();
|
||||||
|
|
||||||
let const_1 = else_b.build(Constant(I32(1))).unwrap();
|
let const_1 = else_b.build("const", Constant(I32(1))).unwrap();
|
||||||
let const_2 = else_b.build(Constant(I32(2))).unwrap();
|
let const_2 = else_b.build("const", Constant(I32(2))).unwrap();
|
||||||
let param_1 = else_b.build(Sub(param_n, const_1)).unwrap();
|
let param_1 = else_b.build("sub", Sub(param_n, const_1)).unwrap();
|
||||||
let param_2 = else_b.build(Sub(param_n, const_2)).unwrap();
|
let param_2 = else_b.build("sub", Sub(param_n, const_2)).unwrap();
|
||||||
let call_1 = else_b
|
let call_1 = else_b
|
||||||
.build(FunctionCall(fibonacci.value(), vec![param_1]))
|
.build("fibonacci", FunctionCall(fibonacci.value(), vec![param_1]))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let call_2 = else_b
|
let call_2 = else_b
|
||||||
.build(FunctionCall(fibonacci.value(), vec![param_2]))
|
.build("fibonacci", FunctionCall(fibonacci.value(), vec![param_2]))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let add = else_b.build(Add(call_1, call_2)).unwrap();
|
let add = else_b.build("add", Add(call_1, call_2)).unwrap();
|
||||||
|
|
||||||
else_b.terminate(TerminatorKind::Ret(add)).unwrap();
|
else_b.terminate(TerminatorKind::Ret(add)).unwrap();
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ pub struct BlockHolder {
|
|||||||
pub struct InstructionHolder {
|
pub struct InstructionHolder {
|
||||||
pub(crate) value: InstructionValue,
|
pub(crate) value: InstructionValue,
|
||||||
pub(crate) data: InstructionData,
|
pub(crate) data: InstructionData,
|
||||||
|
pub(crate) name: String,
|
||||||
pub(crate) record: Option<InstructionDebugRecordData>,
|
pub(crate) record: Option<InstructionDebugRecordData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,6 +150,7 @@ impl Builder {
|
|||||||
&self,
|
&self,
|
||||||
block_val: &BlockValue,
|
block_val: &BlockValue,
|
||||||
data: InstructionData,
|
data: InstructionData,
|
||||||
|
name: String,
|
||||||
) -> Result<InstructionValue, ()> {
|
) -> Result<InstructionValue, ()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut modules = self.modules.borrow_mut();
|
let mut modules = self.modules.borrow_mut();
|
||||||
@ -159,6 +161,7 @@ impl Builder {
|
|||||||
block.instructions.push(InstructionHolder {
|
block.instructions.push(InstructionHolder {
|
||||||
value,
|
value,
|
||||||
data,
|
data,
|
||||||
|
name,
|
||||||
record: None,
|
record: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -743,6 +743,7 @@ impl InstructionHolder {
|
|||||||
_block: LLVMBasicBlockRef,
|
_block: LLVMBasicBlockRef,
|
||||||
) -> LLVMValue {
|
) -> LLVMValue {
|
||||||
let _ty = self.value.get_type(module.builder).unwrap();
|
let _ty = self.value.get_type(module.builder).unwrap();
|
||||||
|
let name = into_cstring(self.name.clone());
|
||||||
let val = unsafe {
|
let val = unsafe {
|
||||||
use super::Instr::*;
|
use super::Instr::*;
|
||||||
match &self.data.kind {
|
match &self.data.kind {
|
||||||
@ -751,22 +752,22 @@ impl InstructionHolder {
|
|||||||
Add(lhs, rhs) => {
|
Add(lhs, rhs) => {
|
||||||
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
||||||
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
||||||
LLVMBuildAdd(module.builder_ref, lhs_val, rhs_val, c"add".as_ptr())
|
LLVMBuildAdd(module.builder_ref, lhs_val, rhs_val, name.as_ptr())
|
||||||
}
|
}
|
||||||
Sub(lhs, rhs) => {
|
Sub(lhs, rhs) => {
|
||||||
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
||||||
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
||||||
LLVMBuildSub(module.builder_ref, lhs_val, rhs_val, c"sub".as_ptr())
|
LLVMBuildSub(module.builder_ref, lhs_val, rhs_val, name.as_ptr())
|
||||||
}
|
}
|
||||||
Mult(lhs, rhs) => {
|
Mult(lhs, rhs) => {
|
||||||
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
||||||
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
||||||
LLVMBuildMul(module.builder_ref, lhs_val, rhs_val, c"mul".as_ptr())
|
LLVMBuildMul(module.builder_ref, lhs_val, rhs_val, name.as_ptr())
|
||||||
}
|
}
|
||||||
And(lhs, rhs) => {
|
And(lhs, rhs) => {
|
||||||
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
||||||
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
||||||
LLVMBuildAnd(module.builder_ref, lhs_val, rhs_val, c"and".as_ptr())
|
LLVMBuildAnd(module.builder_ref, lhs_val, rhs_val, name.as_ptr())
|
||||||
}
|
}
|
||||||
ICmp(pred, lhs, rhs) => {
|
ICmp(pred, lhs, rhs) => {
|
||||||
let lhs = module.values.get(&lhs).unwrap();
|
let lhs = module.values.get(&lhs).unwrap();
|
||||||
@ -777,7 +778,7 @@ impl InstructionHolder {
|
|||||||
pred.as_llvm_int(lhs._ty.signed()),
|
pred.as_llvm_int(lhs._ty.signed()),
|
||||||
lhs.value_ref,
|
lhs.value_ref,
|
||||||
rhs_val,
|
rhs_val,
|
||||||
c"icmp".as_ptr(),
|
name.as_ptr(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
FunctionCall(function_value, instruction_values) => {
|
FunctionCall(function_value, instruction_values) => {
|
||||||
@ -797,7 +798,7 @@ impl InstructionHolder {
|
|||||||
fun.value_ref,
|
fun.value_ref,
|
||||||
param_list.as_mut_ptr(),
|
param_list.as_mut_ptr(),
|
||||||
param_list.len() as u32,
|
param_list.len() as u32,
|
||||||
c"call".as_ptr(),
|
name.as_ptr(),
|
||||||
);
|
);
|
||||||
if is_void {
|
if is_void {
|
||||||
LLVMContextSetDiscardValueNames(module.context_ref, 0);
|
LLVMContextSetDiscardValueNames(module.context_ref, 0);
|
||||||
@ -814,7 +815,7 @@ impl InstructionHolder {
|
|||||||
let phi = LLVMBuildPhi(
|
let phi = LLVMBuildPhi(
|
||||||
module.builder_ref,
|
module.builder_ref,
|
||||||
_ty.as_llvm(module.context_ref, &module.types),
|
_ty.as_llvm(module.context_ref, &module.types),
|
||||||
c"phi".as_ptr(),
|
name.as_ptr(),
|
||||||
);
|
);
|
||||||
LLVMAddIncoming(
|
LLVMAddIncoming(
|
||||||
phi,
|
phi,
|
||||||
@ -827,13 +828,13 @@ impl InstructionHolder {
|
|||||||
Alloca(ty) => LLVMBuildAlloca(
|
Alloca(ty) => LLVMBuildAlloca(
|
||||||
module.builder_ref,
|
module.builder_ref,
|
||||||
ty.as_llvm(module.context_ref, &module.types),
|
ty.as_llvm(module.context_ref, &module.types),
|
||||||
c"alloca".as_ptr(),
|
name.as_ptr(),
|
||||||
),
|
),
|
||||||
Load(ptr, ty) => LLVMBuildLoad2(
|
Load(ptr, ty) => LLVMBuildLoad2(
|
||||||
module.builder_ref,
|
module.builder_ref,
|
||||||
ty.as_llvm(module.context_ref, &module.types),
|
ty.as_llvm(module.context_ref, &module.types),
|
||||||
module.values.get(&ptr).unwrap().value_ref,
|
module.values.get(&ptr).unwrap().value_ref,
|
||||||
c"load".as_ptr(),
|
name.as_ptr(),
|
||||||
),
|
),
|
||||||
Store(ptr, val) => {
|
Store(ptr, val) => {
|
||||||
let store = LLVMBuildStore(
|
let store = LLVMBuildStore(
|
||||||
@ -849,7 +850,7 @@ impl InstructionHolder {
|
|||||||
module.builder_ref,
|
module.builder_ref,
|
||||||
ty.as_llvm(module.context_ref, &module.types),
|
ty.as_llvm(module.context_ref, &module.types),
|
||||||
array_len,
|
array_len,
|
||||||
c"array_alloca".as_ptr(),
|
name.as_ptr(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
GetElemPtr(arr, indices) => {
|
GetElemPtr(arr, indices) => {
|
||||||
@ -867,32 +868,26 @@ impl InstructionHolder {
|
|||||||
module.values.get(arr).unwrap().value_ref,
|
module.values.get(arr).unwrap().value_ref,
|
||||||
llvm_indices.as_mut_ptr(),
|
llvm_indices.as_mut_ptr(),
|
||||||
llvm_indices.len() as u32,
|
llvm_indices.len() as u32,
|
||||||
into_cstring(format!("array_gep")).as_ptr(),
|
name.as_ptr(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
GetStructElemPtr(struct_val, idx) => {
|
GetStructElemPtr(struct_val, idx) => {
|
||||||
let t = struct_val.get_type(module.builder).unwrap();
|
let t = struct_val.get_type(module.builder).unwrap();
|
||||||
let Type::Ptr(struct_t) = t else { panic!() };
|
let Type::Ptr(struct_t) = t else { panic!() };
|
||||||
|
|
||||||
let type_fmt = if let Type::CustomType(type_val) = *struct_t {
|
|
||||||
format!("M{}T{}", type_val.0.0, type_val.1)
|
|
||||||
} else {
|
|
||||||
format!("{:?}", struct_t)
|
|
||||||
};
|
|
||||||
|
|
||||||
LLVMBuildStructGEP2(
|
LLVMBuildStructGEP2(
|
||||||
module.builder_ref,
|
module.builder_ref,
|
||||||
struct_t.as_llvm(module.context_ref, &module.types),
|
struct_t.as_llvm(module.context_ref, &module.types),
|
||||||
module.values.get(struct_val).unwrap().value_ref,
|
module.values.get(struct_val).unwrap().value_ref,
|
||||||
*idx,
|
*idx,
|
||||||
into_cstring(format!("struct.{}.{}.gep", type_fmt, idx)).as_ptr(),
|
name.as_ptr(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ExtractValue(agg_val, idx) => LLVMBuildExtractValue(
|
ExtractValue(agg_val, idx) => LLVMBuildExtractValue(
|
||||||
module.builder_ref,
|
module.builder_ref,
|
||||||
module.values.get(agg_val).unwrap().value_ref,
|
module.values.get(agg_val).unwrap().value_ref,
|
||||||
*idx,
|
*idx,
|
||||||
c"extract".as_ptr(),
|
name.as_ptr(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -71,6 +71,7 @@ impl Debug for BlockHolder {
|
|||||||
impl Debug for InstructionHolder {
|
impl Debug for InstructionHolder {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
self.value.fmt(f)?;
|
self.value.fmt(f)?;
|
||||||
|
write!(f, " ({})", self.name)?;
|
||||||
f.write_str(" = ")?;
|
f.write_str(" = ")?;
|
||||||
self.data.fmt(f)
|
self.data.fmt(f)
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,11 @@ pub struct Block<'builder> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'builder> Block<'builder> {
|
impl<'builder> Block<'builder> {
|
||||||
pub fn build(&mut self, instruction: Instr) -> Result<InstructionValue, ()> {
|
pub fn build<T: Into<String>>(
|
||||||
|
&mut self,
|
||||||
|
name: T,
|
||||||
|
instruction: Instr,
|
||||||
|
) -> Result<InstructionValue, ()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.builder.add_instruction(
|
self.builder.add_instruction(
|
||||||
&self.value,
|
&self.value,
|
||||||
@ -213,6 +217,7 @@ impl<'builder> Block<'builder> {
|
|||||||
location: None,
|
location: None,
|
||||||
meta: None,
|
meta: None,
|
||||||
},
|
},
|
||||||
|
name.into(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,11 +343,19 @@ impl mir::Module {
|
|||||||
let mut stack_values = HashMap::new();
|
let mut stack_values = HashMap::new();
|
||||||
for (i, (p_name, p_ty)) in mir_function.parameters.iter().enumerate() {
|
for (i, (p_name, p_ty)) in mir_function.parameters.iter().enumerate() {
|
||||||
// Codegen actual parameters
|
// Codegen actual parameters
|
||||||
let param = entry.build(Instr::Param(i)).unwrap();
|
let arg_name = format!("arg.{}", p_name);
|
||||||
let alloca = entry
|
let param = entry
|
||||||
.build(Instr::Alloca(p_ty.get_type(&type_values, &types)))
|
.build(format!("{}.get", arg_name), Instr::Param(i))
|
||||||
|
.unwrap();
|
||||||
|
let alloca = entry
|
||||||
|
.build(
|
||||||
|
&arg_name,
|
||||||
|
Instr::Alloca(p_ty.get_type(&type_values, &types)),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
entry
|
||||||
|
.build(format!("{}.store", arg_name), Instr::Store(alloca, param))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
entry.build(Instr::Store(alloca, param)).unwrap();
|
|
||||||
stack_values.insert(
|
stack_values.insert(
|
||||||
p_name.clone(),
|
p_name.clone(),
|
||||||
StackValue(
|
StackValue(
|
||||||
@ -470,15 +478,22 @@ impl mir::Statement {
|
|||||||
mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => {
|
mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => {
|
||||||
let value = expression.codegen(scope, &state).unwrap();
|
let value = expression.codegen(scope, &state).unwrap();
|
||||||
|
|
||||||
|
dbg!(&name);
|
||||||
let alloca = scope
|
let alloca = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Alloca(ty.get_type(scope.type_values, scope.types)))
|
.build(
|
||||||
|
name,
|
||||||
|
Instr::Alloca(ty.get_type(scope.type_values, scope.types)),
|
||||||
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location);
|
.maybe_location(&mut scope.block, location);
|
||||||
|
|
||||||
let store = scope
|
let store = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Store(alloca, value.instr()))
|
.build(
|
||||||
|
format!("{}.store", name),
|
||||||
|
Instr::Store(alloca, value.instr()),
|
||||||
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location);
|
.maybe_location(&mut scope.block, location);
|
||||||
|
|
||||||
@ -522,6 +537,12 @@ impl mir::Statement {
|
|||||||
|
|
||||||
let rhs_value = rhs.codegen(scope, state)?;
|
let rhs_value = rhs.codegen(scope, state)?;
|
||||||
|
|
||||||
|
let backing_var = if let Some(var) = lhs.backing_var() {
|
||||||
|
&format!("store.{}", var.1)
|
||||||
|
} else {
|
||||||
|
"store"
|
||||||
|
};
|
||||||
|
|
||||||
match lhs_value.0 {
|
match lhs_value.0 {
|
||||||
StackValueKind::Immutable(_) => {
|
StackValueKind::Immutable(_) => {
|
||||||
panic!("Tried to assign to immutable!")
|
panic!("Tried to assign to immutable!")
|
||||||
@ -529,7 +550,7 @@ impl mir::Statement {
|
|||||||
StackValueKind::Mutable(instr) => {
|
StackValueKind::Mutable(instr) => {
|
||||||
scope
|
scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Store(instr, rhs_value.instr()))
|
.build(backing_var, Instr::Store(instr, rhs_value.instr()))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location);
|
.maybe_location(&mut scope.block, location);
|
||||||
}
|
}
|
||||||
@ -572,10 +593,13 @@ impl mir::Expression {
|
|||||||
v.0.derive(
|
v.0.derive(
|
||||||
scope
|
scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Load(
|
.build(
|
||||||
|
format!("{}", varref.1),
|
||||||
|
Instr::Load(
|
||||||
v.0.instr(),
|
v.0.instr(),
|
||||||
inner.get_type(scope.type_values, scope.types),
|
inner.get_type(scope.type_values, scope.types),
|
||||||
))
|
),
|
||||||
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
),
|
),
|
||||||
*inner.clone(),
|
*inner.clone(),
|
||||||
@ -604,20 +628,20 @@ impl mir::Expression {
|
|||||||
Some(StackValue(
|
Some(StackValue(
|
||||||
StackValueKind::Immutable(match binop {
|
StackValueKind::Immutable(match binop {
|
||||||
mir::BinaryOperator::Add => {
|
mir::BinaryOperator::Add => {
|
||||||
scope.block.build(Instr::Add(lhs, rhs)).unwrap()
|
scope.block.build("add", Instr::Add(lhs, rhs)).unwrap()
|
||||||
}
|
}
|
||||||
mir::BinaryOperator::Minus => {
|
mir::BinaryOperator::Minus => {
|
||||||
scope.block.build(Instr::Sub(lhs, rhs)).unwrap()
|
scope.block.build("sub", Instr::Sub(lhs, rhs)).unwrap()
|
||||||
}
|
}
|
||||||
mir::BinaryOperator::Mult => {
|
mir::BinaryOperator::Mult => {
|
||||||
scope.block.build(Instr::Mult(lhs, rhs)).unwrap()
|
scope.block.build("mul", Instr::Mult(lhs, rhs)).unwrap()
|
||||||
}
|
}
|
||||||
mir::BinaryOperator::And => {
|
mir::BinaryOperator::And => {
|
||||||
scope.block.build(Instr::And(lhs, rhs)).unwrap()
|
scope.block.build("and", Instr::And(lhs, rhs)).unwrap()
|
||||||
}
|
}
|
||||||
mir::BinaryOperator::Cmp(l) => scope
|
mir::BinaryOperator::Cmp(l) => scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::ICmp(l.int_predicate(), lhs, rhs))
|
.build("cmp", Instr::ICmp(l.int_predicate(), lhs, rhs))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
}),
|
}),
|
||||||
TypeKind::U32,
|
TypeKind::U32,
|
||||||
@ -643,7 +667,10 @@ impl mir::Expression {
|
|||||||
StackValueKind::Immutable(
|
StackValueKind::Immutable(
|
||||||
scope
|
scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::FunctionCall(callee.ir.value(), params))
|
.build(
|
||||||
|
call.name.clone(),
|
||||||
|
Instr::FunctionCall(callee.ir.value(), params),
|
||||||
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
),
|
),
|
||||||
ret_type,
|
ret_type,
|
||||||
@ -673,12 +700,15 @@ impl mir::Expression {
|
|||||||
|
|
||||||
let first = scope
|
let first = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Constant(ConstValue::U32(0)))
|
.build("array.zero", Instr::Constant(ConstValue::U32(0)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let ptr = scope
|
let ptr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::GetElemPtr(kind.instr(), vec![first, idx]))
|
.build(
|
||||||
|
format!("array.gep"),
|
||||||
|
Instr::GetElemPtr(kind.instr(), vec![first, idx]),
|
||||||
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location);
|
.maybe_location(&mut scope.block, location);
|
||||||
|
|
||||||
@ -694,10 +724,13 @@ impl mir::Expression {
|
|||||||
kind.derive(
|
kind.derive(
|
||||||
scope
|
scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Load(
|
.build(
|
||||||
|
"array.load",
|
||||||
|
Instr::Load(
|
||||||
ptr,
|
ptr,
|
||||||
val_t.get_type(scope.type_values, scope.types),
|
val_t.get_type(scope.type_values, scope.types),
|
||||||
))
|
),
|
||||||
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location),
|
.maybe_location(&mut scope.block, location),
|
||||||
),
|
),
|
||||||
@ -727,37 +760,45 @@ impl mir::Expression {
|
|||||||
Box::new(elem_ty_kind.get_type(scope.type_values, scope.types)),
|
Box::new(elem_ty_kind.get_type(scope.type_values, scope.types)),
|
||||||
instr_list.len() as u64,
|
instr_list.len() as u64,
|
||||||
);
|
);
|
||||||
|
let array_name = format!("{}.{}", elem_ty_kind, instr_list.len());
|
||||||
|
let load_n = format!("{}.load", array_name);
|
||||||
|
|
||||||
let array = scope
|
let array = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Alloca(array_ty.clone()))
|
.build(&array_name, Instr::Alloca(array_ty.clone()))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location);
|
.maybe_location(&mut scope.block, location);
|
||||||
|
|
||||||
for (index, instr) in instr_list.iter().enumerate() {
|
for (index, instr) in instr_list.iter().enumerate() {
|
||||||
|
let gep_n = format!("{}.{}.gep", array_name, index);
|
||||||
|
let store_n = format!("{}.{}.store", array_name, index);
|
||||||
|
|
||||||
let index_expr = scope
|
let index_expr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Constant(ConstValue::U32(index as u32)))
|
.build(
|
||||||
|
index.to_string(),
|
||||||
|
Instr::Constant(ConstValue::U32(index as u32)),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let first = scope
|
let first = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Constant(ConstValue::U32(0)))
|
.build("zero", Instr::Constant(ConstValue::U32(0)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let ptr = scope
|
let ptr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::GetElemPtr(array, vec![first, index_expr]))
|
.build(gep_n, Instr::GetElemPtr(array, vec![first, index_expr]))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location);
|
.maybe_location(&mut scope.block, location);
|
||||||
scope
|
scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Store(ptr, *instr))
|
.build(store_n, Instr::Store(ptr, *instr))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location);
|
.maybe_location(&mut scope.block, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
let array_val = scope
|
let array_val = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Load(array, array_ty))
|
.build(load_n, Instr::Load(array, array_ty))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location);
|
.maybe_location(&mut scope.block, location);
|
||||||
|
|
||||||
@ -779,9 +820,15 @@ impl mir::Expression {
|
|||||||
scope.get_typedef(&name).unwrap().kind.clone();
|
scope.get_typedef(&name).unwrap().kind.clone();
|
||||||
let idx = struct_ty.find_index(field).unwrap();
|
let idx = struct_ty.find_index(field).unwrap();
|
||||||
|
|
||||||
|
let gep_n = format!("{}.{}.gep", name, field);
|
||||||
|
let load_n = format!("{}.{}.load", name, field);
|
||||||
|
|
||||||
let value = scope
|
let value = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::GetStructElemPtr(struct_val.instr(), idx as u32))
|
.build(
|
||||||
|
gep_n,
|
||||||
|
Instr::GetStructElemPtr(struct_val.instr(), idx as u32),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// value.maybe_location(&mut scope.block, location);
|
// value.maybe_location(&mut scope.block, location);
|
||||||
@ -791,10 +838,13 @@ impl mir::Expression {
|
|||||||
struct_val.0.derive(
|
struct_val.0.derive(
|
||||||
scope
|
scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Load(
|
.build(
|
||||||
|
load_n,
|
||||||
|
Instr::Load(
|
||||||
value,
|
value,
|
||||||
type_kind.get_type(scope.type_values, scope.types),
|
type_kind.get_type(scope.type_values, scope.types),
|
||||||
))
|
),
|
||||||
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
),
|
),
|
||||||
struct_ty.get_field_ty(&field).unwrap().clone(),
|
struct_ty.get_field_ty(&field).unwrap().clone(),
|
||||||
@ -808,22 +858,28 @@ impl mir::Expression {
|
|||||||
}
|
}
|
||||||
mir::ExprKind::Struct(name, items) => {
|
mir::ExprKind::Struct(name, items) => {
|
||||||
let struct_ty = Type::CustomType(*scope.type_values.get(name)?);
|
let struct_ty = Type::CustomType(*scope.type_values.get(name)?);
|
||||||
|
|
||||||
|
let load_n = format!("{}.load", name);
|
||||||
|
|
||||||
let struct_ptr = scope
|
let struct_ptr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Alloca(struct_ty.clone()))
|
.build(name, Instr::Alloca(struct_ty.clone()))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location);
|
.maybe_location(&mut scope.block, location);
|
||||||
|
|
||||||
for (i, (_, exp)) in items.iter().enumerate() {
|
for (i, (field_n, exp)) in items.iter().enumerate() {
|
||||||
|
let gep_n = format!("{}.{}.gep", name, field_n);
|
||||||
|
let store_n = format!("{}.{}.store", name, field_n);
|
||||||
|
|
||||||
let elem_ptr = scope
|
let elem_ptr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::GetStructElemPtr(struct_ptr, i as u32))
|
.build(gep_n, Instr::GetStructElemPtr(struct_ptr, i as u32))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location);
|
.maybe_location(&mut scope.block, location);
|
||||||
if let Some(val) = exp.codegen(scope, state) {
|
if let Some(val) = exp.codegen(scope, state) {
|
||||||
scope
|
scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Store(elem_ptr, val.instr()))
|
.build(store_n, Instr::Store(elem_ptr, val.instr()))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location);
|
.maybe_location(&mut scope.block, location);
|
||||||
}
|
}
|
||||||
@ -831,7 +887,7 @@ impl mir::Expression {
|
|||||||
|
|
||||||
let struct_val = scope
|
let struct_val = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Load(struct_ptr, struct_ty))
|
.build(load_n, Instr::Load(struct_ptr, struct_ty))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Some(StackValue(
|
Some(StackValue(
|
||||||
@ -919,7 +975,10 @@ impl mir::IfExpression {
|
|||||||
incoming.extend(else_res.clone());
|
incoming.extend(else_res.clone());
|
||||||
let instr = scope
|
let instr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Phi(incoming.iter().map(|i| i.instr()).collect()))
|
.build(
|
||||||
|
"phi",
|
||||||
|
Instr::Phi(incoming.iter().map(|i| i.instr()).collect()),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
use StackValueKind::*;
|
use StackValueKind::*;
|
||||||
@ -957,7 +1016,9 @@ impl mir::CmpOperator {
|
|||||||
|
|
||||||
impl mir::Literal {
|
impl mir::Literal {
|
||||||
fn as_const(&self, block: &mut Block) -> InstructionValue {
|
fn as_const(&self, block: &mut Block) -> InstructionValue {
|
||||||
block.build(self.as_const_kind()).unwrap()
|
block
|
||||||
|
.build(format!("{}", self), self.as_const_kind())
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_const_kind(&self) -> Instr {
|
fn as_const_kind(&self) -> Instr {
|
||||||
|
Loading…
Reference in New Issue
Block a user