diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-03-10 22:46:59 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-03-10 22:46:59 +0800 |
commit | 13e2409860c35c8693675d7c2c9b202741f7ddde (patch) | |
tree | d77de837c5628950c4af64d525d813a98ce0f651 /src | |
parent | 33ec90c927fef40bdfc86554285ddaf5ff772d15 (diff) | |
download | mrust-13e2409860c35c8693675d7c2c9b202741f7ddde.tar.gz |
MIR Optimise - basic size_of replacemnt
Diffstat (limited to 'src')
-rw-r--r-- | src/mir/optimise.cpp | 31 | ||||
-rw-r--r-- | src/trans/target.cpp | 134 | ||||
-rw-r--r-- | src/trans/target.hpp | 15 |
3 files changed, 166 insertions, 14 deletions
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp index 5062fcf7..173b5d7e 100644 --- a/src/mir/optimise.cpp +++ b/src/mir/optimise.cpp @@ -15,6 +15,7 @@ #include <mir/visit_crate_mir.hpp> #include <algorithm> #include <iomanip> +#include <trans/target.hpp> namespace { ::MIR::BasicBlockId get_new_target(const ::MIR::TypeResolve& state, ::MIR::BasicBlockId bb) @@ -1738,23 +1739,25 @@ bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn) const auto& tef = te.fcn.as_Intrinsic(); if( tef.name == "size_of" ) { - //size_t size_val = 0; - //if( Target_GetSizeOf(tef.params.m_types.at(0), size_val) ) - //{ - // bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(te.ret_val), ::MIR::Constant::make_Uint(size_val) })); - // bb.terminator = ::MIR::Terminator::make_Goto(te.ret_block); - // changed = true; - //} + size_t size_val = 0; + if( Target_GetSizeOf(state.sp, tef.params.m_types.at(0), size_val) ) + { + auto val = ::MIR::Constant::make_Uint({ size_val, ::HIR::CoreType::Usize }); + bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(te.ret_val), mv$(val) })); + bb.terminator = ::MIR::Terminator::make_Goto(te.ret_block); + changed = true; + } } else if( tef.name == "align_of" ) { - //size_t size_val = 0; - //if( Target_GetAlignOf(tef.params.m_types.at(0), size_val) ) - //{ - // bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(te.ret_val), ::MIR::Constant::make_Uint(size_val) })); - // bb.terminator = ::MIR::Terminator::make_Goto(te.ret_block); - // changed = true; - //} + size_t align_val = 0; + if( Target_GetAlignOf(state.sp, tef.params.m_types.at(0), align_val) ) + { + auto val = ::MIR::Constant::make_Uint({ align_val, ::HIR::CoreType::Usize }); + bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(te.ret_val), mv$(val) })); + bb.terminator = ::MIR::Terminator::make_Goto(te.ret_block); + changed = true; + } } // NOTE: Quick special-case for bswap<u8> (a no-op) else if( tef.name == "bswap" && tef.params.m_types.at(0) == ::HIR::CoreType::U8 ) diff --git a/src/trans/target.cpp b/src/trans/target.cpp new file mode 100644 index 00000000..21555101 --- /dev/null +++ b/src/trans/target.cpp @@ -0,0 +1,134 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * trans/target.cpp + * - Target-specific information + */ +#include "target.hpp" + +// TODO: Replace with target selection +#define POINTER_SIZE_BYTES 8 + +bool Target_GetSizeAndAlignOf(const Span& sp, const ::HIR::TypeRef& ty, size_t& out_size, size_t& out_align) +{ + TU_MATCHA( (ty.m_data), (te), + (Infer, + BUG(sp, "sizeof on _ type"); + ), + (Diverge, + out_size = 0; + out_align = 0; + return true; + ), + (Primitive, + switch(te) + { + case ::HIR::CoreType::Bool: + case ::HIR::CoreType::U8: + case ::HIR::CoreType::I8: + out_size = 1; + out_align = 1; + return true; + case ::HIR::CoreType::U16: + case ::HIR::CoreType::I16: + out_size = 2; + out_align = 2; + return true; + case ::HIR::CoreType::U32: + case ::HIR::CoreType::I32: + case ::HIR::CoreType::Char: + out_size = 4; + out_align = 4; + return true; + case ::HIR::CoreType::U64: + case ::HIR::CoreType::I64: + out_size = 8; + out_align = 8; + return true; + case ::HIR::CoreType::U128: + case ::HIR::CoreType::I128: + out_size = 16; + // TODO: If i128 is emulated, this can be 8 + out_align = 16; + return true; + case ::HIR::CoreType::Usize: + case ::HIR::CoreType::Isize: + out_size = POINTER_SIZE_BYTES; + out_align = POINTER_SIZE_BYTES; + return true; + case ::HIR::CoreType::F32: + out_size = 4; + out_align = 4; + return true; + case ::HIR::CoreType::F64: + out_size = 8; + out_align = 8; + return true; + case ::HIR::CoreType::Str: + BUG(sp, "sizeof on a `str` - unsized"); + } + ), + (Path, + // TODO: + return false; + ), + (Generic, + // Unknown - return false + return false; + ), + (TraitObject, + BUG(sp, "sizeof on a trait object - unsized"); + ), + (ErasedType, + BUG(sp, "sizeof on an erased type - shouldn't exist"); + ), + (Array, + // TODO: + size_t size; + if( !Target_GetSizeAndAlignOf(sp, *te.inner, size,out_align) ) + return false; + size *= te.size_val; + ), + (Slice, + BUG(sp, "sizeof on a slice - unsized"); + ), + (Tuple, + out_size = 0; + out_align = 0; + + // TODO: Struct reordering + for(const auto& t : te) + { + size_t size, align; + if( !Target_GetSizeAndAlignOf(sp, t, size,align) ) + return false; + out_size += size; + out_align = ::std::max(out_align, align); + } + ), + (Borrow, + // TODO + ), + (Pointer, + // TODO + ), + (Function, + // Pointer size + ), + (Closure, + // TODO. + ) + ) + return false; +} +bool Target_GetSizeOf(const Span& sp, const ::HIR::TypeRef& ty, size_t& out_size) +{ + size_t ignore_align; + return Target_GetSizeAndAlignOf(sp, ty, out_size, ignore_align); +} +bool Target_GetAlignOf(const Span& sp, const ::HIR::TypeRef& ty, size_t& out_align) +{ + size_t ignore_size; + return Target_GetSizeAndAlignOf(sp, ty, ignore_size, out_align); +} diff --git a/src/trans/target.hpp b/src/trans/target.hpp new file mode 100644 index 00000000..1c081b54 --- /dev/null +++ b/src/trans/target.hpp @@ -0,0 +1,15 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * trans/target.hpp + * - Target-specific information + */ +#pragma once + +#include <cstddef> +#include <hir/type.hpp> + +extern bool Target_GetSizeOf(const Span& sp, const ::HIR::TypeRef& ty, size_t& out_size); +extern bool Target_GetAlignOf(const Span& sp, const ::HIR::TypeRef& ty, size_t& out_align); + |