From 9bb6bac24cdcbcc1ed00a9aea7f4c97b221696e1 Mon Sep 17 00:00:00 2001 From: Isaiah Norton Date: Sat, 4 Apr 2015 10:11:33 -0400 Subject: [PATCH] code_llvm: strip IR metadata IR, add _raw version This makes IR output easier to use with external tools. --- base/interactiveutil.jl | 3 ++- base/reflection.jl | 13 +++++++++---- src/codegen.cpp | 29 ++++++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/base/interactiveutil.jl b/base/interactiveutil.jl index 8ea025758c8674..c041fb73f24c2a 100644 --- a/base/interactiveutil.jl +++ b/base/interactiveutil.jl @@ -264,7 +264,8 @@ function gen_call_with_extracted_types(fcn, ex0) exret end -for fname in [:which, :less, :edit, :code_typed, :code_warntype, :code_lowered, :code_llvm, :code_native] +for fname in [:which, :less, :edit, :code_typed, :code_warntype, + :code_lowered, :code_llvm, :code_llvm_raw, :code_native] @eval begin macro ($fname)(ex0) gen_call_with_extracted_types($(Expr(:quote,fname)), ex0) diff --git a/base/reflection.jl b/base/reflection.jl index a6e787ec7d163c..168035a5aacad4 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -156,7 +156,8 @@ done(mt::MethodTable, i::()) = true uncompressed_ast(l::LambdaStaticData) = isa(l.ast,Expr) ? l.ast : ccall(:jl_uncompress_ast, Any, (Any,Any), l, l.ast) -function _dump_function(f, t::ANY, native, wrapper) +# Printing code representations in IR and assembly +function _dump_function(f, t::ANY, native, wrapper, strip_ir_metadata) llvmf = ccall(:jl_get_llvmf, Ptr{Void}, (Any, Any, Bool), f, t, wrapper) if llvmf == C_NULL @@ -166,15 +167,19 @@ function _dump_function(f, t::ANY, native, wrapper) if (native) str = ccall(:jl_dump_function_asm, Any, (Ptr{Void},), llvmf)::ByteString else - str = ccall(:jl_dump_function_ir, Any, (Ptr{Void},), llvmf)::ByteString + str = ccall(:jl_dump_function_ir, Any, + (Ptr{Void}, Bool), llvmf, strip_ir_metadata)::ByteString end return str end -code_llvm(io::IO, f::Function, types::(Type...)) = print(io, _dump_function(f, types, false, false)) +code_llvm(io::IO, f::Function, types::(Type...), strip_ir_metadata = true) = + print(io, _dump_function(f, types, false, false, strip_ir_metadata)) code_llvm(f::Function, types::(Type...)) = code_llvm(STDOUT, f, types) -code_native(io::IO, f::Function, types::(Type...)) = print(io, _dump_function(f, types, true, false)) +code_llvm_raw(f::Function, types::(Type...)) = code_llvm(STDOUT, f, types, false) + +code_native(io::IO, f::Function, types::(Type...)) = print(io, _dump_function(f, types, true, false, false)) code_native(f::Function, types::(Type...)) = code_native(STDOUT, f, types) function which(f::ANY, t::(Type...)) diff --git a/src/codegen.cpp b/src/codegen.cpp index 58334da330cf3f..ea6aabddb6e63e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -944,13 +944,36 @@ void jl_dump_asm_internal(uintptr_t Fptr, size_t Fsize, size_t slide, formatted_raw_ostream &stream); extern "C" -const jl_value_t *jl_dump_function_ir(void *f) +const jl_value_t *jl_dump_function_ir(void *f, bool strip_ir_metadata) { std::string code; llvm::raw_string_ostream stream(code); - Function *llvmf = (Function*)f; - llvmf->print(stream); + + if (!strip_ir_metadata) { + // print the function IR as-is + llvmf->print(stream); + } else { + // make a copy of the function and strip metadata from the copy + llvm::ValueToValueMapTy VMap; + Function* f2 = llvm::CloneFunction(llvmf, VMap, false); + + for (auto f2_bb = f2->getBasicBlockList().begin(); + f2_bb != f2->getBasicBlockList().end(); ++f2_bb) { + for (auto f2_il = (*f2_bb).getInstList().begin(); + f2_il != (*f2_bb).getInstList().end(); ++f2_il) { + SmallVector, 4> MDForInst; + (*f2_il).getAllMetadata(MDForInst); + for (auto md_iter = MDForInst.begin(); + md_iter != MDForInst.end(); ++md_iter) { + (*f2_il).setMetadata((*md_iter).first, NULL); + } + } + } + f2->print(stream); + delete f2; + } + return jl_cstr_to_string(const_cast(stream.str().c_str())); }