Permalink
Browse files

Start of new LLVM JIT

  • Loading branch information...
1 parent d32a63e commit a3526242f9419fa3561d3aa27897b17489c3ff53 Evan Phoenix committed Apr 20, 2009
Showing 4,347 changed files with 890 additions and 694,668 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
View
@@ -5,6 +5,10 @@ $trace ||= false
$VERBOSE = true
$verbose = Rake.application.options.trace || ARGV.delete("-v")
+if !$verbose and respond_to?(:verbose)
+ verbose(false) if verbose() == :default
+end
+
$dlext = Config::CONFIG["DLEXT"]
$compiler = nil
View
@@ -15,7 +15,7 @@ task :extensions => %w[
# Ask the VM to build an extension from source.
#
def compile_extension(path, flags = "-p -I#{Dir.pwd}/vm/capi")
- cflags = Object.const_get(:FLAGS).reject {|f| f =~ /-Wno-deprecated|-Weffc\+\+/ }
+ cflags = BASIC_FLAGS.reject {|f| f =~ /-Wno-deprecated|-Weffc\+\+/ }
cflags.each {|flag| flags << " -C,#{flag}" }
View
@@ -0,0 +1,61 @@
+namespace :jit do
+ task :generate_header do
+ classes = %w!rubinius::ObjectHeader
+ rubinius::Object
+ rubinius::CallFrame
+ rubinius::UnwindInfo
+ rubinius::VariableScope
+ rubinius::CompiledMethod
+ rubinius::Executable
+ rubinius::Dispatch
+ rubinius::Arguments
+ rubinius::Tuple
+ rubinius::Array
+ rubinius::Class
+ rubinius::Module
+ rubinius::StaticScope
+ rubinius::InstructionSequence
+ jit_state!
+ require 'tempfile'
+
+ files = %w!vm/call_frame.hpp vm/arguments.hpp vm/dispatch.hpp!
+ path = "llvm-type-temp.cpp"
+
+ File.open(path, "w+") do |f|
+ files.each do |file|
+ f.puts "#include \"#{file}\""
+ end
+
+ i = 0
+ classes.each do |klass|
+ f.puts "void useme#{i}(#{klass}* thing);"
+ f.puts "void blah#{i}(#{klass}* thing) { useme#{i}(thing); }"
+ i += 1
+ end
+ end
+
+ str = `llvm-g++ -I. -Ivm -Ivm/external_libs/libtommath -emit-llvm -S -o - "#{path}"`
+
+ types = []
+
+ str.split("\n").each do |line|
+ classes.each do |klass|
+ if /%"?struct.#{klass}(::\$[^\s]+)?"? = type/.match(line)
+ types << line
+ end
+ end
+ end
+
+ opaque = %w!VM TypeInfo VMMethod Fixnum Symbol!
+
+ File.open("vm/gen/types.ll","w+") do |f|
+ opaque.each do |o|
+ f.puts "%\"struct.rubinius::#{o}\" = type opaque"
+ end
+ f.puts(*types)
+ end
+
+ `llvm-as < vm/gen/types.ll > vm/gen/types.bc`
+ `llc -march=cpp -cppgen=contents -f -o vm/gen/types.cpp vm/gen/types.bc`
+ end
+end
View
@@ -27,7 +27,7 @@ else
LLVM_STYLE = "Release"
end
-LLVM_ENABLE = false
+LLVM_ENABLE = true
ENV.delete 'CDPATH' # confuses llvm_config
@@ -43,7 +43,7 @@ end
# tests << 'vm/test/test_instructions.hpp'
tests.uniq!
-subdirs = %w!builtin capi parser util instruments gc!
+subdirs = %w!builtin capi parser util instruments gc llvm!
srcs = FileList["vm/*.{cpp,c}"]
subdirs.each do |dir|
@@ -173,17 +173,22 @@ INCLUDES = EX_INC + %w[/usr/local/include vm/test/cxxtest vm . vm/assembler
INCLUDES.map! { |f| "-I#{f}" }
# Default build options
-FLAGS = %W[ -pipe -Wall -Wno-deprecated
+BASIC_FLAGS = %W[ -pipe -Wall -Wno-deprecated
-DBASE_PATH=\\"#{RBX_BASE_PATH}\\"
-DRBA_PATH=\\"#{RBX_RBA_PATH}\\"
]
+FLAGS = BASIC_FLAGS.dup
+
if RUBY_PLATFORM =~ /darwin/i && `sw_vers` =~ /10\.4/
FLAGS.concat %w(-DHAVE_STRLCAT -DHAVE_STRLCPY)
end
if LLVM_ENABLE
- FLAGS << "-DENABLE_LLVM"
+ # FLAGS << "-DENABLE_LLVM"
+ llvm_flags = `#{LLVM_CONFIG} --cflags`.split(/\s+/)
+ llvm_flags.delete_if { |e| e.index("-O") == 0 }
+ FLAGS.concat llvm_flags
end
BUILD_PRETASKS = []
@@ -201,12 +206,6 @@ def compile_c(obj, src)
flags << "-emit-llvm"
end
- if LLVM_ENABLE and !defined? $llvm_c then
- $llvm_c = `#{LLVM_CONFIG} --cflags`.split(/\s+/)
- $llvm_c.delete_if { |e| e.index("-O") == 0 }
- flags.concat $llvm_c
- end
-
# GROSS
if src == "vm/test/runner.cpp"
flags.delete_if { |f| /-O.*/.match(f) }
@@ -541,16 +540,16 @@ file "vm/instructions.o" => "vm/gen/instructions.cpp" do
compile_c "vm/instructions.o", "vm/gen/instructions.cpp"
end
-file "vm/gen/instructions.cpp" => %w[vm/llvm/instructions.cpp vm/instructions.rb] + hdrs do
- ruby "vm/codegen/rubypp.rb", "vm/llvm/instructions.cpp", "vm/gen/instructions.cpp"
+file "vm/gen/instructions.cpp" => %w[vm/template/instructions.cpp vm/instructions.rb] + hdrs do
+ ruby "vm/codegen/rubypp.rb", "vm/template/instructions.cpp", "vm/gen/instructions.cpp"
end
#
-#rubypp_task 'vm/instructions.o', 'vm/llvm/instructions.cpp', 'vm/instructions.rb', *hdrs do |path|
+#rubypp_task 'vm/instructions.o', 'vm/template/instructions.cpp', 'vm/instructions.rb', *hdrs do |path|
# compile_c 'vm/instructions.o', path
#end
-rubypp_task 'vm/instructions.bc', 'vm/llvm/instructions.cpp', *hdrs do |path|
+rubypp_task 'vm/instructions.bc', 'vm/template/instructions.cpp', *hdrs do |path|
sh "llvm-g++ -emit-llvm -Ivm -Ivm/external_libs/libffi/include -c -o vm/instructions.bc #{path}"
end
@@ -582,7 +581,7 @@ namespace :vm do
puts "CC/LD vm/test/coverage/runner"
begin
path = "vm/gen/instructions.cpp"
- ruby 'vm/codegen/rubypp.rb', "vm/llvm/instructions.cpp", path
+ ruby 'vm/codegen/rubypp.rb', "vm/template/instructions.cpp", path
sh "g++ -fprofile-arcs -ftest-coverage #{flags} -o vm/test/coverage/runner vm/test/runner.cpp vm/*.cpp vm/builtin/*.cpp #{path} #{$link_opts} #{(ex_libs + EXTERNALS).join(' ')}"
puts "RUN vm/test/coverage/runner"
View
@@ -0,0 +1,20 @@
+file = ARGV.shift
+klass = ARGV.shift
+
+require 'tempfile'
+
+path = "llvm-type-temp.cpp"
+
+File.open(path, "w+") do |f|
+ f.puts "#include \"#{file}\""
+ f.puts "void useme(#{klass}* thing);"
+ f.puts "void blah(#{klass}* thing) { useme(thing); }"
+end
+
+str = `llvm-g++ -I. -I.. -Iexternal_libs/libtommath -emit-llvm -S -o - "#{path}"`
+
+str.split("\n").each do |line|
+ if /%"?struct.#{klass}"? = type/.match(line)
+ puts line
+ end
+end
@@ -165,9 +165,7 @@ namespace rubinius {
formalize(state, false);
}
- JITCompiler jit;
- jit.compile(state, backend_method_);
- return MachineMethod::create(state, backend_method_, jit);
+ return MachineMethod::create(state, backend_method_);
}
bool CompiledMethod::is_rescue_target(STATE, int ip) {
@@ -8,6 +8,8 @@
#include "detection.hpp"
+#include "llvm/jit.hpp"
+
// #define MM_DEBUG
namespace rubinius {
@@ -72,22 +74,45 @@ namespace rubinius {
return mm;
}
+ MachineMethod* MachineMethod::create(STATE, VMMethod* vmm) {
+ LLVMCompiler jit;
+ jit.compile(state, vmm);
+
+ MachineMethod* mm = state->new_struct<MachineMethod>(G(machine_method));
+
+ mm->vmmethod_ = vmm;
+ mm->code_size_ = 0;
+ mm->set_function(jit.function_pointer(state));
+ mm->relocations_ = 0;
+ mm->virtual2native_ = 0;
+ mm->comments_ = 0;
+
+ mm->jit_data_ = reinterpret_cast<void*>(jit.llvm_function(state));
+ return mm;
+ }
+
void* MachineMethod::resolve_virtual_ip(int ip) {
CodeMap::iterator i = virtual2native_->find(ip);
if(i == virtual2native_->end()) return NULL;
return i->second;
}
- Object* MachineMethod::show() {
- std::cout << "== stats ==\n";
- std::cout << "number of bytecodes: " << vmmethod_->total << "\n";
- std::cout << " bytes of assembley: " << code_size_ << "\n";
- double ratio = (double)code_size_ / (double)vmmethod_->total;
- std::cout << " direct ratio: " << ratio << "\n";
- ratio = (double)code_size_ / ((double)vmmethod_->total * sizeof(rubinius::opcode));
- std::cout << " memory ratio: " << ratio << "\n";
- std::cout << "\n== x86 assembly ==\n";
- assembler_x86::AssemblerX86::show_buffer(function(), code_size_, false, comments_);
+ Object* MachineMethod::show(STATE) {
+ if(code_size_ == 0) {
+ std::cout << "== llvm assembly ==\n";
+ LLVMCompiler::show_assembly(state, reinterpret_cast<llvm::Function*>(jit_data_));
+ } else {
+ std::cout << "== stats ==\n";
+ std::cout << "number of bytecodes: " << vmmethod_->total << "\n";
+ std::cout << " bytes of assembley: " << code_size_ << "\n";
+ double ratio = (double)code_size_ / (double)vmmethod_->total;
+ std::cout << " direct ratio: " << ratio << "\n";
+ ratio = (double)code_size_ / ((double)vmmethod_->total * sizeof(rubinius::opcode));
+ std::cout << " memory ratio: " << ratio << "\n";
+ std::cout << "\n== x86 assembly ==\n";
+ assembler_x86::AssemblerX86::show_buffer(function(), code_size_, false, comments_);
+ }
+
return Qnil;
}
@@ -20,10 +20,12 @@ namespace rubinius {
assembler::Relocation** relocations_;
void* function_;
+ void* jit_data_;
public:
static void init(STATE);
static MachineMethod* create(STATE, VMMethod* vmm, JITCompiler& jit);
+ static MachineMethod* create(STATE, VMMethod* vmm);
void* function() {
return reinterpret_cast<void*>(function_);
@@ -34,10 +36,10 @@ namespace rubinius {
}
// Used for debugging. Gives us a place to break on before entering jit'd code
- static Object * run_code(STATE, VMMethod* const vmm, CallFrame* const call_frame);
+ static Object* run_code(STATE, VMMethod* const vmm, CallFrame* const call_frame);
// Ruby.primitive :machine_method_show
- Object* show();
+ Object* show(STATE);
// Ruby.primitive :machine_method_activate
Object* activate();
@@ -0,0 +1,14 @@
+require "#{File.dirname(__FILE__)}/../../kernel/compiler/iseq"
+
+File.open "#{File.dirname(__FILE__)}/../gen/inst_list.hpp", "w" do |f|
+ InstructionSet::OpCodes.each do |ins|
+ case ins.arg_count
+ when 2
+ f.puts "HANDLE_INST2(#{ins.bytecode}, #{ins.opcode});"
+ when 1
+ f.puts "HANDLE_INST1(#{ins.bytecode}, #{ins.opcode});"
+ when 0
+ f.puts "HANDLE_INST0(#{ins.bytecode}, #{ins.opcode});"
+ end
+ end
+end
View
@@ -0,0 +1,45 @@
+require "#{File.dirname(__FILE__)}/../../kernel/compiler/iseq"
+
+puts "template <class SubClass>"
+puts "void VisitInstructions::drive() {"
+puts " switch(current_instruction()) {"
+
+InstructionSet::OpCodes.each do |ins|
+ puts " case #{ins.bytecode}: // #{ins.opcode}"
+ case ins.arg_count
+ when 2
+ puts " SPECIFIC->visit_#{ins.opcode}(opcode_arg(0), opcode_arg(1));"
+ when 1
+ puts " SPECIFIC->visit_#{ins.opcode}(opcode_arg(0));"
+ when 0
+ puts " SPECIFIC->visit_#{ins.opcode}();"
+ else
+ raise "huh?"
+ end
+ puts " advance(#{ins.arg_count + 1});"
+ puts " return;"
+end
+
+puts " }"
+
+puts "}"
+
+InstructionSet::OpCodes.each do |ins|
+ puts "template <class SubClass>"
+ case ins.arg_count
+ when 2
+ puts "void VisitInstructions::visit_#{ins.opcode}(opcode arg1, opcode arg2)"
+ puts "{\n SPECIFIC->visit(#{ins.bytecode}, arg1, arg2);\n}"
+ when 1
+ puts "void VisitInstructions::visit_#{ins.opcode}(opcode arg1)"
+ puts "{\n SPECIFIC->visit(#{ins.bytecode}, arg1, -1);\n}"
+ when 0
+ puts "void VisitInstructions::visit_#{ins.opcode}()"
+ puts "{\n SPECIFIC->visit(#{ins.bytecode}, -1, -1);\n}"
+ else
+ raise "huh?"
+ end
+
+ puts
+
+end
Oops, something went wrong.

0 comments on commit a352624

Please sign in to comment.