Add Array support to llvm-lib
This commit is contained in:
		
							parent
							
								
									515c031f19
								
							
						
					
					
						commit
						a2e52e0bd2
					
				@ -277,6 +277,14 @@ impl Builder {
 | 
				
			|||||||
                        Err(())
 | 
					                        Err(())
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                Extract(list, idx) => {
 | 
				
			||||||
 | 
					                    let list_ty = list.get_type(&self)?;
 | 
				
			||||||
 | 
					                    if let Type::Array(_, len) = list_ty {
 | 
				
			||||||
 | 
					                        if len < idx { Ok(()) } else { Err(()) }
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        Err(())
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -338,6 +346,11 @@ impl InstructionValue {
 | 
				
			|||||||
                Alloca(_, ty) => Ok(Type::Ptr(Box::new(ty.clone()))),
 | 
					                Alloca(_, ty) => Ok(Type::Ptr(Box::new(ty.clone()))),
 | 
				
			||||||
                Load(_, ty) => Ok(ty.clone()),
 | 
					                Load(_, ty) => Ok(ty.clone()),
 | 
				
			||||||
                Store(_, value) => value.get_type(builder),
 | 
					                Store(_, value) => value.get_type(builder),
 | 
				
			||||||
 | 
					                Extract(arr, _) => match arr.get_type(builder) {
 | 
				
			||||||
 | 
					                    Ok(Type::Array(elem_t, _)) => Ok(*elem_t),
 | 
				
			||||||
 | 
					                    Ok(_) => Err(()),
 | 
				
			||||||
 | 
					                    Err(_) => Err(()),
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -358,6 +371,10 @@ impl ConstValue {
 | 
				
			|||||||
            ConstValue::U64(_) => U64,
 | 
					            ConstValue::U64(_) => U64,
 | 
				
			||||||
            ConstValue::U128(_) => U128,
 | 
					            ConstValue::U128(_) => U128,
 | 
				
			||||||
            ConstValue::Bool(_) => Bool,
 | 
					            ConstValue::Bool(_) => Bool,
 | 
				
			||||||
 | 
					            ConstValue::ConstArray(arr) => Array(
 | 
				
			||||||
 | 
					                Box::new(arr.iter().map(|a| a.get_type()).next().unwrap_or(Void)),
 | 
				
			||||||
 | 
					                arr.len() as u32,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -378,6 +395,7 @@ impl Type {
 | 
				
			|||||||
            Type::Bool => true,
 | 
					            Type::Bool => true,
 | 
				
			||||||
            Type::Void => false,
 | 
					            Type::Void => false,
 | 
				
			||||||
            Type::Ptr(_) => false,
 | 
					            Type::Ptr(_) => false,
 | 
				
			||||||
 | 
					            Type::Array(_, _) => false,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -396,6 +414,7 @@ impl Type {
 | 
				
			|||||||
            Type::Bool => false,
 | 
					            Type::Bool => false,
 | 
				
			||||||
            Type::Void => false,
 | 
					            Type::Void => false,
 | 
				
			||||||
            Type::Ptr(_) => false,
 | 
					            Type::Ptr(_) => false,
 | 
				
			||||||
 | 
					            Type::Array(_, _) => false,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -349,6 +349,12 @@ impl InstructionHolder {
 | 
				
			|||||||
                    module.values.get(&val).unwrap().value_ref,
 | 
					                    module.values.get(&val).unwrap().value_ref,
 | 
				
			||||||
                    module.values.get(&ptr).unwrap().value_ref,
 | 
					                    module.values.get(&ptr).unwrap().value_ref,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
 | 
					                Extract(instruction_value, idx) => LLVMBuildExtractValue(
 | 
				
			||||||
 | 
					                    module.builder_ref,
 | 
				
			||||||
 | 
					                    module.values.get(instruction_value).unwrap().value_ref,
 | 
				
			||||||
 | 
					                    *idx as u32,
 | 
				
			||||||
 | 
					                    c"extract".as_ptr(),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        LLVMValue {
 | 
					        LLVMValue {
 | 
				
			||||||
@ -415,18 +421,36 @@ impl ConstValue {
 | 
				
			|||||||
    fn as_llvm(&self, context: LLVMContextRef) -> LLVMValueRef {
 | 
					    fn as_llvm(&self, context: LLVMContextRef) -> LLVMValueRef {
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            let t = self.get_type().as_llvm(context);
 | 
					            let t = self.get_type().as_llvm(context);
 | 
				
			||||||
            match *self {
 | 
					            match self {
 | 
				
			||||||
                ConstValue::Bool(val) => LLVMConstInt(t, val as u64, 1),
 | 
					                ConstValue::Bool(val) => LLVMConstInt(t, *val as u64, 1),
 | 
				
			||||||
                ConstValue::I8(val) => LLVMConstInt(t, val as u64, 1),
 | 
					                ConstValue::I8(val) => LLVMConstInt(t, *val as u64, 1),
 | 
				
			||||||
                ConstValue::I16(val) => LLVMConstInt(t, val as u64, 1),
 | 
					                ConstValue::I16(val) => LLVMConstInt(t, *val as u64, 1),
 | 
				
			||||||
                ConstValue::I32(val) => LLVMConstInt(t, val as u64, 1),
 | 
					                ConstValue::I32(val) => LLVMConstInt(t, *val as u64, 1),
 | 
				
			||||||
                ConstValue::I64(val) => LLVMConstInt(t, val as u64, 1),
 | 
					                ConstValue::I64(val) => LLVMConstInt(t, *val as u64, 1),
 | 
				
			||||||
                ConstValue::I128(val) => LLVMConstInt(t, val as u64, 1),
 | 
					                ConstValue::I128(val) => LLVMConstInt(t, *val as u64, 1),
 | 
				
			||||||
                ConstValue::U8(val) => LLVMConstInt(t, val as u64, 1),
 | 
					                ConstValue::U8(val) => LLVMConstInt(t, *val as u64, 1),
 | 
				
			||||||
                ConstValue::U16(val) => LLVMConstInt(t, val as u64, 1),
 | 
					                ConstValue::U16(val) => LLVMConstInt(t, *val as u64, 1),
 | 
				
			||||||
                ConstValue::U32(val) => LLVMConstInt(t, val as u64, 1),
 | 
					                ConstValue::U32(val) => LLVMConstInt(t, *val as u64, 1),
 | 
				
			||||||
                ConstValue::U64(val) => LLVMConstInt(t, val as u64, 1),
 | 
					                ConstValue::U64(val) => LLVMConstInt(t, *val as u64, 1),
 | 
				
			||||||
                ConstValue::U128(val) => LLVMConstInt(t, val as u64, 1),
 | 
					                ConstValue::U128(val) => LLVMConstInt(t, *val as u64, 1),
 | 
				
			||||||
 | 
					                ConstValue::ConstArray(const_values) => {
 | 
				
			||||||
 | 
					                    let elem_ty = const_values
 | 
				
			||||||
 | 
					                        .iter()
 | 
				
			||||||
 | 
					                        .map(|e| e.get_type())
 | 
				
			||||||
 | 
					                        .next()
 | 
				
			||||||
 | 
					                        .unwrap_or(Type::Void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    let mut elems = const_values
 | 
				
			||||||
 | 
					                        .iter()
 | 
				
			||||||
 | 
					                        .map(|e| e.as_llvm(context))
 | 
				
			||||||
 | 
					                        .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    LLVMConstArray(
 | 
				
			||||||
 | 
					                        elem_ty.as_llvm(context),
 | 
				
			||||||
 | 
					                        elems.as_mut_ptr(),
 | 
				
			||||||
 | 
					                        elems.len() as u32,
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -445,6 +469,7 @@ impl Type {
 | 
				
			|||||||
                Bool => LLVMInt1TypeInContext(context),
 | 
					                Bool => LLVMInt1TypeInContext(context),
 | 
				
			||||||
                Void => LLVMVoidType(),
 | 
					                Void => LLVMVoidType(),
 | 
				
			||||||
                Ptr(ty) => LLVMPointerType(ty.as_llvm(context), 0),
 | 
					                Ptr(ty) => LLVMPointerType(ty.as_llvm(context), 0),
 | 
				
			||||||
 | 
					                Array(elem_t, len) => LLVMArrayType(elem_t.as_llvm(context), *len as u32),
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -88,18 +88,19 @@ impl Debug for InstructionValue {
 | 
				
			|||||||
impl Debug for Instr {
 | 
					impl Debug for Instr {
 | 
				
			||||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
					    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            Self::Param(nth) => fmt_call(f, &"Param", &nth),
 | 
					            Instr::Param(nth) => fmt_call(f, &"Param", &nth),
 | 
				
			||||||
            Self::Constant(c) => c.fmt(f),
 | 
					            Instr::Constant(c) => c.fmt(f),
 | 
				
			||||||
            Self::Add(lhs, rhs) => fmt_binop(f, lhs, &"+", rhs),
 | 
					            Instr::Add(lhs, rhs) => fmt_binop(f, lhs, &"+", rhs),
 | 
				
			||||||
            Self::Sub(lhs, rhs) => fmt_binop(f, lhs, &"-", rhs),
 | 
					            Instr::Sub(lhs, rhs) => fmt_binop(f, lhs, &"-", rhs),
 | 
				
			||||||
            Self::Mult(lhs, rhs) => fmt_binop(f, lhs, &"*", rhs),
 | 
					            Instr::Mult(lhs, rhs) => fmt_binop(f, lhs, &"*", rhs),
 | 
				
			||||||
            Self::And(lhs, rhs) => fmt_binop(f, lhs, &"&&", rhs),
 | 
					            Instr::And(lhs, rhs) => fmt_binop(f, lhs, &"&&", rhs),
 | 
				
			||||||
            Self::Phi(val) => fmt_call(f, &"Phi", &val),
 | 
					            Instr::Phi(val) => fmt_call(f, &"Phi", &val),
 | 
				
			||||||
            Self::ICmp(cmp, lhs, rhs) => fmt_binop(f, lhs, cmp, rhs),
 | 
					            Instr::ICmp(cmp, lhs, rhs) => fmt_binop(f, lhs, cmp, rhs),
 | 
				
			||||||
            Self::FunctionCall(fun, params) => fmt_call(f, fun, params),
 | 
					            Instr::FunctionCall(fun, params) => fmt_call(f, fun, params),
 | 
				
			||||||
            Instr::Alloca(name, ty) => write!(f, "alloca<{:?}>({})", ty, name),
 | 
					            Instr::Alloca(name, ty) => write!(f, "alloca<{:?}>({})", ty, name),
 | 
				
			||||||
            Instr::Load(val, ty) => write!(f, "load<{:?}>({:?})", ty, val),
 | 
					            Instr::Load(val, ty) => write!(f, "load<{:?}>({:?})", ty, val),
 | 
				
			||||||
            Instr::Store(ptr, val) => write!(f, "store({:?} = {:?})", ptr, val),
 | 
					            Instr::Store(ptr, val) => write!(f, "store({:?} = {:?})", ptr, val),
 | 
				
			||||||
 | 
					            Instr::Extract(instruction_value, idx) => fmt_index(f, instruction_value, idx),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -128,6 +129,17 @@ fn fmt_call(
 | 
				
			|||||||
    f.write_char(')')
 | 
					    f.write_char(')')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn fmt_index(
 | 
				
			||||||
 | 
					    f: &mut std::fmt::Formatter<'_>,
 | 
				
			||||||
 | 
					    fun: &impl std::fmt::Debug,
 | 
				
			||||||
 | 
					    params: &impl std::fmt::Debug,
 | 
				
			||||||
 | 
					) -> std::fmt::Result {
 | 
				
			||||||
 | 
					    fun.fmt(f)?;
 | 
				
			||||||
 | 
					    f.write_char('[')?;
 | 
				
			||||||
 | 
					    params.fmt(f)?;
 | 
				
			||||||
 | 
					    f.write_char(']')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Debug for CmpPredicate {
 | 
					impl Debug for CmpPredicate {
 | 
				
			||||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
					    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
 | 
				
			|||||||
@ -177,6 +177,7 @@ pub enum Instr {
 | 
				
			|||||||
    Alloca(String, Type),
 | 
					    Alloca(String, Type),
 | 
				
			||||||
    Load(InstructionValue, Type),
 | 
					    Load(InstructionValue, Type),
 | 
				
			||||||
    Store(InstructionValue, InstructionValue),
 | 
					    Store(InstructionValue, InstructionValue),
 | 
				
			||||||
 | 
					    Extract(InstructionValue, u32),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Integer Comparison
 | 
					    /// Integer Comparison
 | 
				
			||||||
    ICmp(CmpPredicate, InstructionValue, InstructionValue),
 | 
					    ICmp(CmpPredicate, InstructionValue, InstructionValue),
 | 
				
			||||||
@ -199,6 +200,7 @@ pub enum Type {
 | 
				
			|||||||
    Bool,
 | 
					    Bool,
 | 
				
			||||||
    Void,
 | 
					    Void,
 | 
				
			||||||
    Ptr(Box<Type>),
 | 
					    Ptr(Box<Type>),
 | 
				
			||||||
 | 
					    Array(Box<Type>, u32),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, Hash)]
 | 
					#[derive(Debug, Clone, Hash)]
 | 
				
			||||||
@ -214,6 +216,7 @@ pub enum ConstValue {
 | 
				
			|||||||
    U64(u64),
 | 
					    U64(u64),
 | 
				
			||||||
    U128(u128),
 | 
					    U128(u128),
 | 
				
			||||||
    Bool(bool),
 | 
					    Bool(bool),
 | 
				
			||||||
 | 
					    ConstArray(Vec<ConstValue>),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone, Hash)]
 | 
					#[derive(Clone, Hash)]
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user