diff options
author | John Hodge <tpg@mutabah.net> | 2016-08-20 14:12:21 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-08-20 14:12:21 +0800 |
commit | 610b81b2546a36f937c45ec870c874630c2b35f5 (patch) | |
tree | 36bd3f72230f6d24a5305e62fdb362ee7c4ea67c | |
parent | d9a88049e0ab150657253ce2f0a6fffe96ffddef (diff) | |
download | mrust-610b81b2546a36f937c45ec870c874630c2b35f5.tar.gz |
MIR Dump - Rough dump pass, exposes junk data somewhere
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | src/main.cpp | 7 | ||||
-rw-r--r-- | src/mir/dump.cpp | 380 | ||||
-rw-r--r-- | src/mir/main_bindings.hpp | 2 | ||||
-rw-r--r-- | src/mir/mir.hpp | 5 |
5 files changed, 393 insertions, 2 deletions
@@ -58,6 +58,7 @@ OBJ += hir_typeck/expr_cs.o OBJ += hir_typeck/expr_check.o OBJ += hir_expand/annotate_value_usage.o hir_expand/closures.o hir_expand/ufcs_everything.o OBJ += mir/mir.o mir/mir_ptr.o +OBJ += mir/dump.o OBJ += mir/from_hir.o mir/from_hir_match.o PCHS := ast/ast.hpp diff --git a/src/main.cpp b/src/main.cpp index 33d81473..eade3522 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,8 @@ void init_debug_list() g_debug_disable_map.insert( "Resolve" );
g_debug_disable_map.insert( "Resolve UFCS paths" );
g_debug_disable_map.insert( "Typecheck Expressions" );
+ g_debug_disable_map.insert( "Typecheck Expressions (validate)" );
+ g_debug_disable_map.insert( "Dump HIR" );
}
bool debug_enabled()
{
@@ -236,6 +238,11 @@ int main(int argc, char *argv[]) // Validate the MIR
// TODO: ^
+
+ CompilePhaseV("Dump MIR", [&]() {
+ ::std::ofstream os (FMT(params.outfile << "_3_mir.rs"));
+ MIR_Dump( os, *hir_crate );
+ });
// Generate code for non-generic public items (if requested)
diff --git a/src/mir/dump.cpp b/src/mir/dump.cpp new file mode 100644 index 00000000..f1e1cf22 --- /dev/null +++ b/src/mir/dump.cpp @@ -0,0 +1,380 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * mir/dump.cpp + * - Dump MIR for functions (semi-flattened) + */ +#include "main_bindings.hpp" +#include <hir/visitor.hpp> +#include "mir.hpp" + +namespace { + + class TreeVisitor: + public ::HIR::Visitor + { + ::std::ostream& m_os; + unsigned int m_indent_level; + + public: + TreeVisitor(::std::ostream& os): + m_os(os), + m_indent_level(0) + { + } + + void visit_type_impl(::HIR::TypeImpl& impl) override + { + m_os << indent() << "impl" << impl.m_params.fmt_args() << " " << impl.m_type << "\n"; + if( ! impl.m_params.m_bounds.empty() ) + { + m_os << indent() << " " << impl.m_params.fmt_bounds() << "\n"; + } + m_os << indent() << "{\n"; + inc_indent(); + ::HIR::Visitor::visit_type_impl(impl); + dec_indent(); + m_os << indent() << "}\n"; + } + virtual void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override + { + m_os << indent() << "impl" << impl.m_params.fmt_args() << " " << trait_path << impl.m_trait_args << " for " << impl.m_type << "\n"; + if( ! impl.m_params.m_bounds.empty() ) + { + m_os << indent() << " " << impl.m_params.fmt_bounds() << "\n"; + } + m_os << indent() << "{\n"; + inc_indent(); + ::HIR::Visitor::visit_trait_impl(trait_path, impl); + dec_indent(); + m_os << indent() << "}\n"; + } + void visit_marker_impl(const ::HIR::SimplePath& trait_path, ::HIR::MarkerImpl& impl) override + { + m_os << indent() << "impl" << impl.m_params.fmt_args() << " " << (impl.is_positive ? "" : "!") << trait_path << impl.m_trait_args << " for " << impl.m_type << "\n"; + if( ! impl.m_params.m_bounds.empty() ) + { + m_os << indent() << " " << impl.m_params.fmt_bounds() << "\n"; + } + m_os << indent() << "{ }\n"; + } + + // - Type Items + void visit_type_alias(::HIR::ItemPath p, ::HIR::TypeAlias& item) override + { + m_os << indent() << "type " << p.get_name() << item.m_params.fmt_args() << " = " << item.m_type << item.m_params.fmt_bounds() << "\n"; + } + void visit_trait(::HIR::ItemPath p, ::HIR::Trait& item) override + { + m_os << indent() << "trait " << p.get_name() << item.m_params.fmt_args() << "\n"; + if( ! item.m_params.m_bounds.empty() ) + { + m_os << indent() << " " << item.m_params.fmt_bounds() << "\n"; + } + m_os << indent() << "{\n"; + inc_indent(); + ::HIR::Visitor::visit_trait(p, item); + dec_indent(); + m_os << indent() << "}\n"; + } + + void visit_function(::HIR::ItemPath p, ::HIR::Function& item) override + { + m_os << indent(); + if( item.m_const ) + m_os << "const "; + if( item.m_unsafe ) + m_os << "unsafe "; + if( item.m_abi != "rust" ) + m_os << "extern \"" << item.m_abi << "\" "; + m_os << "fn " << p.get_name() << item.m_params.fmt_args() << "("; + for(const auto& arg : item.m_args) + { + m_os << arg.first << ": " << arg.second << ", "; + } + m_os << ") -> " << item.m_return << "\n"; + if( ! item.m_params.m_bounds.empty() ) + { + m_os << indent() << " " << item.m_params.fmt_bounds() << "\n"; + } + + if( item.m_code ) + { + m_os << indent() << "{\n"; + inc_indent(); + this->dump_mir(*item.m_code.m_mir); + dec_indent(); + m_os << indent() << "}\n"; + } + else + { + m_os << indent() << " ;\n"; + } + } + + + void dump_mir(const ::MIR::Function& fcn) + { + for(unsigned int i = 0; i < fcn.named_variables.size(); i ++) + { + m_os << indent() << "let _#" << i << ": " << fcn.named_variables[i] << ";\n"; + } + for(unsigned int i = 0; i < fcn.temporaries.size(); i ++) + { + m_os << indent() << "let tmp$" << i << ": " << fcn.temporaries[i] << ";\n"; + } + + #define FMT_M(x) FMT_CB(os, this->fmt_val(os,x);) + for(unsigned int i = 0; i < fcn.blocks.size(); i ++) + { + const auto& block = fcn.blocks[i]; + m_os << indent() << "bb" << i << ": {\n"; + inc_indent(); + for(const auto& stmt : block.statements) + { + m_os << indent(); + + TU_MATCHA( (stmt), (e), + (Assign, + m_os << FMT_M(e.dst) << " = " << FMT_M(e.src) << ";\n"; + ), + (Drop, + m_os << "drop(" << FMT_M(e.slot) << ");\n"; + ) + ) + } + + m_os << indent(); + TU_MATCHA( (block.terminator), (e), + (Incomplete, + m_os << "INVALID;\n"; + ), + (Return, + m_os << "return;\n"; + ), + (Diverge, + m_os << "diverge;\n"; + ), + (Goto, + m_os << "goto bb" << e << ";\n"; + ), + (Panic, + m_os << "panic bb" << e.dst << ";\n"; + ), + (If, + m_os << "if " << FMT_M(e.cond) << " { goto bb" << e.bb0 << "; } else { goto bb" << e.bb1 << "; }\n"; + ), + (Switch, + m_os << "switch " << FMT_M(e.val) << " {"; + for(unsigned int j = 0; j < e.targets.size(); j ++) + m_os << j << " => bb" << e.targets[j] << ", "; + m_os << "}\n"; + ), + (Call, + m_os << FMT_M(e.ret_val) << " = (" << FMT_M(e.fcn_val) << ")( "; + for(const auto& arg : e.args) + m_os << FMT_M(arg) << ", "; + m_os << ") goto bb" << e.ret_block << " else bb" << e.panic_block << "\n"; + ) + ) + dec_indent(); + m_os << indent() << "}\n"; + + m_os.flush(); + } + #undef FMT + } + void fmt_val(::std::ostream& os, const ::MIR::LValue& lval) { + TU_MATCHA( (lval), (e), + (Variable, + os << "_#" << e; + ), + (Temporary, + os << "tmp$" << e.idx; + ), + (Argument, + os << "arg$" << e.idx; + ), + (Static, + os << e; + ), + (Return, + os << "RETURN"; + ), + (Field, + os << "("; + fmt_val(os, *e.val); + os << ")." << e.field_index; + ), + (Deref, + os << "*"; + fmt_val(os, *e.val); + ), + (Index, + os << "("; + fmt_val(os, *e.val); + os << ")["; + fmt_val(os, *e.idx); + os << "]"; + ), + (Downcast, + fmt_val(os, *e.val); + os << " as variant" << e.variant_index; + ) + ) + } + void fmt_val(::std::ostream& os, const ::MIR::RValue& rval) { + TU_MATCHA( (rval), (e), + (Use, + fmt_val(os, e); + ), + (Constant, + TU_MATCHA( (e), (ce), + (Int, + os << ce; + ), + (Uint, + os << "0x" << ::std::hex << ce << ::std::dec; + ), + (Float, + os << ce; + ), + (Bool, + os << (ce ? "true" : "false"); + ), + (Bytes, + os << "b\"" << ce << "\""; + ), + (StaticString, + os << "\"" << ce << "\""; + ), + (ItemAddr, + os << "addr " << ce; + ) + ) + ), + (SizedArray, + os << "["; + fmt_val(os, e.val); + os << ";" << e.count << "]"; + ), + (Borrow, + os << "&"; + //os << e.region; + switch(e.type) { + case ::HIR::BorrowType::Shared: break; + case ::HIR::BorrowType::Unique: os << "mut "; break; + case ::HIR::BorrowType::Owned: os << "move "; break; + } + os << "("; + fmt_val(os, e.val); + os << ")"; + ), + (Cast, + os << "("; + fmt_val(os, e.val); + os << ") as " << e.type; + ), + (BinOp, + switch(e.op) + { + case ::MIR::eBinOp::ADD: os << "ADD"; break; + case ::MIR::eBinOp::SUB: os << "SUB"; break; + case ::MIR::eBinOp::MUL: os << "MUL"; break; + case ::MIR::eBinOp::DIV: os << "DIV"; break; + case ::MIR::eBinOp::MOD: os << "MOD"; break; + case ::MIR::eBinOp::ADD_OV: os << "ADD_OV"; break; + case ::MIR::eBinOp::SUB_OV: os << "SUB_OV"; break; + case ::MIR::eBinOp::MUL_OV: os << "MUL_OV"; break; + case ::MIR::eBinOp::DIV_OV: os << "DIV_OV"; break; + //case ::MIR::eBinOp::MOD_OV: os << "MOD_OV"; break; + + case ::MIR::eBinOp::BIT_OR : os << "BIT_OR"; break; + case ::MIR::eBinOp::BIT_AND: os << "BIT_AND"; break; + case ::MIR::eBinOp::BIT_XOR: os << "BIT_XOR"; break; + + case ::MIR::eBinOp::BIT_SHR: os << "BIT_SHR"; break; + case ::MIR::eBinOp::BIT_SHL: os << "BIT_SHL"; break; + + case ::MIR::eBinOp::EQ: os << "EQ"; break; + case ::MIR::eBinOp::NE: os << "NE"; break; + case ::MIR::eBinOp::GT: os << "GT"; break; + case ::MIR::eBinOp::GE: os << "GE"; break; + case ::MIR::eBinOp::LT: os << "LT"; break; + case ::MIR::eBinOp::LE: os << "LE"; break; + } + os << "("; + fmt_val(os, e.val_l); + os << ", "; + fmt_val(os, e.val_r); + os << ")"; + ), + (UniOp, + switch(e.op) + { + case ::MIR::eUniOp::INV: os << "INV"; break; + case ::MIR::eUniOp::NEG: os << "NEG"; break; + } + os << "("; + fmt_val(os, e.val); + os << ")"; + ), + (DstMeta, + os << "META("; + fmt_val(os, e.val); + os << ")"; + ), + (MakeDst, + os << "DST("; + fmt_val(os, e.ptr_val); + os << ", "; + fmt_val(os, e.meta_val); + os << ")"; + ), + (Tuple, + os << "("; + for(const auto& v : e.vals) { + fmt_val(os, v); + os << ", "; + } + os << ")"; + ), + (Array, + os << "["; + for(const auto& v : e.vals) { + fmt_val(os, v); + os << ", "; + } + os << "]"; + ), + (Struct, + os << e.path << " { "; + for(const auto& v : e.vals) { + fmt_val(os, v); + os << ", "; + } + os << "}"; + ) + ) + } + private: + RepeatLitStr indent() const { + return RepeatLitStr { " ", static_cast<int>(m_indent_level) }; + } + void inc_indent() { + m_indent_level ++; + } + void dec_indent() { + m_indent_level --; + } + }; +} + +void MIR_Dump(::std::ostream& sink, const ::HIR::Crate& crate) +{ + TreeVisitor tv { sink }; + + tv.visit_crate( const_cast< ::HIR::Crate&>(crate) ); +} + diff --git a/src/mir/main_bindings.hpp b/src/mir/main_bindings.hpp index 1ece8852..c2169b31 100644 --- a/src/mir/main_bindings.hpp +++ b/src/mir/main_bindings.hpp @@ -6,9 +6,11 @@ * - main.cpp binding */ #pragma once +#include <iostream> namespace HIR { class Crate; } extern void HIR_GenerateMIR(::HIR::Crate& crate); +extern void MIR_Dump(::std::ostream& sink, const ::HIR::Crate& crate); diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp index 1f521ef9..8c94e749 100644 --- a/src/mir/mir.hpp +++ b/src/mir/mir.hpp @@ -135,7 +135,8 @@ TAGGED_UNION(RValue, Use, }) ); -TAGGED_UNION(Terminator, Return, +TAGGED_UNION(Terminator, Incomplete, + (Incomplete, struct {}), (Return, struct {}), (Diverge, struct {}), (Goto, BasicBlockId), @@ -146,7 +147,7 @@ TAGGED_UNION(Terminator, Return, BasicBlockId bb1; }), (Switch, struct { - LValue enum_val; + LValue val; ::std::vector<BasicBlockId> targets; }), (Call, struct { |