From 628ce47b2e0de185e4a199bb6ca59922c7bae929 Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Fri, 24 Jun 2022 18:21:24 -0400 Subject: [PATCH] compiler speed improvement (#1547) --- common/goos/ParseHelpers.h | 2 +- common/versions.h | 6 +- decompiler/main.cpp | 1 - docs/progress-notes/changelog.md | 5 +- goalc/compiler/Compiler.cpp | 215 ++++++------------ goalc/compiler/Compiler.h | 13 ++ goalc/compiler/Util.cpp | 149 ++++++++++++ goalc/compiler/compilation/Atoms.cpp | 4 +- .../compiler/compilation/CompilerControl.cpp | 114 +--------- goalc/compiler/compilation/Macro.cpp | 2 +- goalc/make/Tools.cpp | 7 +- goalc/regalloc/Allocator_v2.cpp | 2 +- goalc/regalloc/IRegSet.h | 2 +- 13 files changed, 254 insertions(+), 268 deletions(-) diff --git a/common/goos/ParseHelpers.h b/common/goos/ParseHelpers.h index 53fe4e1d31..6655584345 100644 --- a/common/goos/ParseHelpers.h +++ b/common/goos/ParseHelpers.h @@ -19,7 +19,7 @@ template void for_each_in_list(const goos::Object& list, T f) { const goos::Object* iter = &list; while (iter->is_pair()) { - auto lap = iter->as_pair(); + const auto& lap = iter->as_pair(); f(lap->car); iter = &lap->cdr; } diff --git a/common/versions.h b/common/versions.h index e414f63f8a..b7e99e9af2 100644 --- a/common/versions.h +++ b/common/versions.h @@ -9,10 +9,8 @@ namespace versions { // language version (OpenGOAL) -constexpr s32 GOAL_VERSION_MAJOR = 0; -constexpr s32 GOAL_VERSION_MINOR = 9; - -constexpr int DECOMPILER_VERSION = 4; +constexpr s32 GOAL_VERSION_MAJOR = 1; +constexpr s32 GOAL_VERSION_MINOR = 0; namespace jak1 { // these versions are from the game diff --git a/decompiler/main.cpp b/decompiler/main.cpp index 70855ac3bb..1cddd23820 100644 --- a/decompiler/main.cpp +++ b/decompiler/main.cpp @@ -29,7 +29,6 @@ int main(int argc, char** argv) { lg::set_stdout_level(lg::level::info); lg::set_flush_level(lg::level::info); lg::initialize(); - lg::info("GOAL Decompiler version {}\n", versions::DECOMPILER_VERSION); init_opcode_info(); diff --git a/docs/progress-notes/changelog.md b/docs/progress-notes/changelog.md index c07624719e..d5d60201ef 100644 --- a/docs/progress-notes/changelog.md +++ b/docs/progress-notes/changelog.md @@ -220,4 +220,7 @@ The compiler is now much more aggressive in where and how it expands macros and handles expressions at compiler time. - Several places where macros could be incorrectly executed more than once (possibly causing unwanted side effects) have been fixed. - Fixed bug in size calculation of non-inline stack arrays. Previous behavior was a compiler assert. -- Correctly handle `mod` for unsigned numbers. Previous behavior was to treat all inputs as 32-bit signed integers. \ No newline at end of file +- Correctly handle `mod` for unsigned numbers. Previous behavior was to treat all inputs as 32-bit signed integers. + +## V1.0 Revised constant propagation, speed improvements +Improved error messages around macros \ No newline at end of file diff --git a/goalc/compiler/Compiler.cpp b/goalc/compiler/Compiler.cpp index f7f94831f3..d0cdda805a 100644 --- a/goalc/compiler/Compiler.cpp +++ b/goalc/compiler/Compiler.cpp @@ -8,6 +8,7 @@ #include "common/goos/PrettyPrinter.h" #include "common/link_types.h" +#include "common/util/FileUtil.h" #include "goalc/make/Tools.h" #include "goalc/regalloc/Allocator.h" @@ -78,37 +79,6 @@ Compiler::~Compiler() { } } -void Compiler::save_repl_history() { - m_repl->save_history(); -} - -void Compiler::print_to_repl(const std::string_view& str) { - m_repl->print_to_repl(str); -} - -std::string Compiler::get_prompt() { - std::string prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::cyan), "g > "); - if (m_listener.is_connected()) { - prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::lime_green), "gc> "); - } - if (m_debugger.is_halted()) { - prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::magenta), "gs> "); - } else if (m_debugger.is_attached()) { - prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::red), "gr> "); - } - return "\033[0m" + prompt; -} - -std::string Compiler::get_repl_input() { - auto str = m_repl->readline(get_prompt()); - if (str) { - m_repl->add_to_history(str); - return str; - } else { - return ""; - } -} - ReplStatus Compiler::handle_repl_string(const std::string& input) { if (input.empty()) { return ReplStatus::OK; @@ -329,74 +299,6 @@ bool Compiler::codegen_and_disassemble_object_file(FileEnv* env, return ok; } -void Compiler::compile_and_send_from_string(const std::string& source_code) { - if (!connect_to_target()) { - throw std::runtime_error( - "Compiler failed to connect to target for compile_and_send_from_string."); - } - - auto code = m_goos.reader.read_from_string(source_code); - auto compiled = compile_object_file("test-code", code, true); - ASSERT(!compiled->is_empty()); - color_object_file(compiled); - auto data = codegen_object_file(compiled); - m_listener.send_code(data); - if (!m_listener.most_recent_send_was_acked()) { - print_compiler_warning("Runtime is not responding after sending test code. Did it crash?\n"); - } -} - -std::vector Compiler::run_test_from_file(const std::string& source_code) { - try { - if (!connect_to_target()) { - throw std::runtime_error("Compiler::run_test_from_file couldn't connect!"); - } - - auto code = m_goos.reader.read_from_file({source_code}); - auto compiled = compile_object_file("test-code", code, true); - if (compiled->is_empty()) { - return {}; - } - color_object_file(compiled); - auto data = codegen_object_file(compiled); - m_listener.record_messages(ListenerMessageKind::MSG_PRINT); - m_listener.send_code(data); - if (!m_listener.most_recent_send_was_acked()) { - print_compiler_warning("Runtime is not responding after sending test code. Did it crash?\n"); - } - return m_listener.stop_recording_messages(); - } catch (std::exception& e) { - fmt::print("[Compiler] Failed to compile test program {}: {}\n", source_code, e.what()); - throw e; - } -} - -std::vector Compiler::run_test_from_string(const std::string& src, - const std::string& obj_name) { - try { - if (!connect_to_target()) { - throw std::runtime_error("Compiler::run_test_from_file couldn't connect!"); - } - - auto code = m_goos.reader.read_from_string({src}); - auto compiled = compile_object_file(obj_name, code, true); - if (compiled->is_empty()) { - return {}; - } - color_object_file(compiled); - auto data = codegen_object_file(compiled); - m_listener.record_messages(ListenerMessageKind::MSG_PRINT); - m_listener.send_code(data); - if (!m_listener.most_recent_send_was_acked()) { - print_compiler_warning("Runtime is not responding after sending test code. Did it crash?\n"); - } - return m_listener.stop_recording_messages(); - } catch (std::exception& e) { - fmt::print("[Compiler] Failed to compile test program from string {}: {}\n", src, e.what()); - throw e; - } -} - bool Compiler::connect_to_target() { if (!m_listener.is_connected()) { for (int i = 0; i < 1000; i++) { @@ -413,52 +315,6 @@ bool Compiler::connect_to_target() { return true; } -/*! - * Just run the front end on a string. Will not do register allocation or code generation. - * Useful for typechecking, defining types, or running strings that invoke the compiler again. - */ -void Compiler::run_front_end_on_string(const std::string& src) { - auto code = m_goos.reader.read_from_string({src}); - compile_object_file("run-on-string", code, true); -} - -/*! - * Just run the front end on a file. Will not do register allocation or code generation. - * Useful for typechecking, defining types, or running strings that invoke the compiler again. - */ -void Compiler::run_front_end_on_file(const std::vector& path) { - auto code = m_goos.reader.read_from_file(path); - compile_object_file("run-on-file", code, true); -} - -/*! - * Run the entire compilation process on the input source code. Will generate an object file, but - * won't save it anywhere. - */ -void Compiler::run_full_compiler_on_string_no_save(const std::string& src, - const std::optional& string_name) { - auto code = m_goos.reader.read_from_string(src, true, string_name); - auto compiled = compile_object_file("run-on-string", code, true); - color_object_file(compiled); - codegen_object_file(compiled); -} - -std::vector Compiler::run_test_no_load(const std::string& source_code) { - auto code = m_goos.reader.read_from_file({source_code}); - compile_object_file("test-code", code, true); - return {}; -} - -void Compiler::shutdown_target() { - if (m_debugger.is_attached()) { - m_debugger.detach(); - } - - if (m_listener.is_connected()) { - m_listener.send_reset(true); - } -} - void Compiler::typecheck(const goos::Object& form, const TypeSpec& expected, const TypeSpec& actual, @@ -487,10 +343,6 @@ void Compiler::typecheck_reg_type_allow_false(const goos::Object& form, typecheck(form, expected, coerce_to_reg_type(actual->type()), error_message); } -bool Compiler::knows_object_file(const std::string& name) { - return m_debugger.knows_object(name); -} - void Compiler::setup_goos_forms() { m_goos.register_form("get-enum-vals", [&](const goos::Object& form, goos::Arguments& args, const std::shared_ptr& env) { @@ -522,3 +374,68 @@ void Compiler::setup_goos_forms() { return goos::build_list(enum_vals); }); } + +void Compiler::asm_file(const CompilationOptions& options) { + auto code = m_goos.reader.read_from_file({options.filename}); + + std::string obj_file_name = options.filename; + + // Extract object name from file name. + for (int idx = int(options.filename.size()) - 1; idx-- > 0;) { + if (options.filename.at(idx) == '\\' || options.filename.at(idx) == '/') { + obj_file_name = options.filename.substr(idx + 1); + break; + } + } + obj_file_name = obj_file_name.substr(0, obj_file_name.find_last_of('.')); + + // COMPILE + auto obj_file = compile_object_file(obj_file_name, code, !options.no_code); + + if (options.color) { + // register allocation + color_object_file(obj_file); + + // code/object file generation + std::vector data; + std::string disasm; + if (options.disassemble) { + codegen_and_disassemble_object_file(obj_file, &data, &disasm); + if (options.disassembly_output_file.empty()) { + printf("%s\n", disasm.c_str()); + } else { + file_util::write_text_file(options.disassembly_output_file, disasm); + } + } else { + data = codegen_object_file(obj_file); + } + + // send to target + if (options.load) { + if (m_listener.is_connected()) { + m_listener.send_code(data, obj_file_name); + } else { + printf("WARNING - couldn't load because listener isn't connected\n"); // todo log warn + } + } + + // save file + if (options.write) { + auto path = file_util::get_file_path({"out", "obj", obj_file_name + ".o"}); + file_util::create_dir_if_needed_for_file(path); + file_util::write_binary_file(path, (void*)data.data(), data.size()); + } + } else { + if (options.load) { + printf("WARNING - couldn't load because coloring is not enabled\n"); + } + + if (options.write) { + printf("WARNING - couldn't write because coloring is not enabled\n"); + } + + if (options.disassemble) { + printf("WARNING - couldn't disassemble because coloring is not enabled\n"); + } + } +} diff --git a/goalc/compiler/Compiler.h b/goalc/compiler/Compiler.h index 19e8761c2d..7a58808bcd 100644 --- a/goalc/compiler/Compiler.h +++ b/goalc/compiler/Compiler.h @@ -26,10 +26,23 @@ enum MathMode { MATH_INT, MATH_BINT, MATH_FLOAT, MATH_INVALID }; enum class ReplStatus { OK, WANT_EXIT, WANT_RELOAD }; +struct CompilationOptions { + std::string filename; // input file + std::string disassembly_output_file; // file to write, containing x86 assembly output + bool load = false; // send to target + bool color = false; // do register allocation/code generation passes + bool write = false; // write object file to out/obj + bool no_code = false; // file shouldn't generate code, throw error if it does + bool disassemble = false; // either print disassembly to stdout or output_file + bool print_time = false; // print timing statistics +}; + class Compiler { public: Compiler(const std::string& user_profile = "#f", std::unique_ptr repl = nullptr); ~Compiler(); + void asm_file(const CompilationOptions& options); + void save_repl_history(); void print_to_repl(const std::string_view& str); std::string get_prompt(); diff --git a/goalc/compiler/Util.cpp b/goalc/compiler/Util.cpp index 38ec370076..0e9f9d8ea3 100644 --- a/goalc/compiler/Util.cpp +++ b/goalc/compiler/Util.cpp @@ -4,6 +4,155 @@ #include "goalc/compiler/Compiler.h" #include "goalc/compiler/IR.h" +void Compiler::save_repl_history() { + m_repl->save_history(); +} + +void Compiler::print_to_repl(const std::string_view& str) { + m_repl->print_to_repl(str); +} + +std::string Compiler::get_prompt() { + std::string prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::cyan), "g > "); + if (m_listener.is_connected()) { + prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::lime_green), "gc> "); + } + if (m_debugger.is_halted()) { + prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::magenta), "gs> "); + } else if (m_debugger.is_attached()) { + prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::red), "gr> "); + } + return "\033[0m" + prompt; +} + +std::string Compiler::get_repl_input() { + auto str = m_repl->readline(get_prompt()); + if (str) { + m_repl->add_to_history(str); + return str; + } else { + return ""; + } +} + +void Compiler::compile_and_send_from_string(const std::string& source_code) { + if (!connect_to_target()) { + throw std::runtime_error( + "Compiler failed to connect to target for compile_and_send_from_string."); + } + + auto code = m_goos.reader.read_from_string(source_code); + auto compiled = compile_object_file("test-code", code, true); + ASSERT(!compiled->is_empty()); + color_object_file(compiled); + auto data = codegen_object_file(compiled); + m_listener.send_code(data); + if (!m_listener.most_recent_send_was_acked()) { + print_compiler_warning("Runtime is not responding after sending test code. Did it crash?\n"); + } +} + +std::vector Compiler::run_test_from_file(const std::string& source_code) { + try { + if (!connect_to_target()) { + throw std::runtime_error("Compiler::run_test_from_file couldn't connect!"); + } + + auto code = m_goos.reader.read_from_file({source_code}); + auto compiled = compile_object_file("test-code", code, true); + if (compiled->is_empty()) { + return {}; + } + color_object_file(compiled); + auto data = codegen_object_file(compiled); + m_listener.record_messages(ListenerMessageKind::MSG_PRINT); + m_listener.send_code(data); + if (!m_listener.most_recent_send_was_acked()) { + print_compiler_warning("Runtime is not responding after sending test code. Did it crash?\n"); + } + return m_listener.stop_recording_messages(); + } catch (std::exception& e) { + fmt::print("[Compiler] Failed to compile test program {}: {}\n", source_code, e.what()); + throw e; + } +} + +std::vector Compiler::run_test_from_string(const std::string& src, + const std::string& obj_name) { + try { + if (!connect_to_target()) { + throw std::runtime_error("Compiler::run_test_from_file couldn't connect!"); + } + + auto code = m_goos.reader.read_from_string({src}); + auto compiled = compile_object_file(obj_name, code, true); + if (compiled->is_empty()) { + return {}; + } + color_object_file(compiled); + auto data = codegen_object_file(compiled); + m_listener.record_messages(ListenerMessageKind::MSG_PRINT); + m_listener.send_code(data); + if (!m_listener.most_recent_send_was_acked()) { + print_compiler_warning("Runtime is not responding after sending test code. Did it crash?\n"); + } + return m_listener.stop_recording_messages(); + } catch (std::exception& e) { + fmt::print("[Compiler] Failed to compile test program from string {}: {}\n", src, e.what()); + throw e; + } +} + +/*! + * Just run the front end on a string. Will not do register allocation or code generation. + * Useful for typechecking, defining types, or running strings that invoke the compiler again. + */ +void Compiler::run_front_end_on_string(const std::string& src) { + auto code = m_goos.reader.read_from_string({src}); + compile_object_file("run-on-string", code, true); +} + +/*! + * Just run the front end on a file. Will not do register allocation or code generation. + * Useful for typechecking, defining types, or running strings that invoke the compiler again. + */ +void Compiler::run_front_end_on_file(const std::vector& path) { + auto code = m_goos.reader.read_from_file(path); + compile_object_file("run-on-file", code, true); +} + +/*! + * Run the entire compilation process on the input source code. Will generate an object file, but + * won't save it anywhere. + */ +void Compiler::run_full_compiler_on_string_no_save(const std::string& src, + const std::optional& string_name) { + auto code = m_goos.reader.read_from_string(src, true, string_name); + auto compiled = compile_object_file("run-on-string", code, true); + color_object_file(compiled); + codegen_object_file(compiled); +} + +std::vector Compiler::run_test_no_load(const std::string& source_code) { + auto code = m_goos.reader.read_from_file({source_code}); + compile_object_file("test-code", code, true); + return {}; +} + +void Compiler::shutdown_target() { + if (m_debugger.is_attached()) { + m_debugger.detach(); + } + + if (m_listener.is_connected()) { + m_listener.send_reset(true); + } +} + +bool Compiler::knows_object_file(const std::string& name) { + return m_debugger.knows_object(name); +} + /*! * Parse arguments into a goos::Arguments format. */ diff --git a/goalc/compiler/compilation/Atoms.cpp b/goalc/compiler/compilation/Atoms.cpp index 49df6d10a3..3d491a129c 100644 --- a/goalc/compiler/compilation/Atoms.cpp +++ b/goalc/compiler/compilation/Atoms.cpp @@ -286,8 +286,8 @@ Val* Compiler::compile_no_const_prop(const goos::Object& code, Env* env) { * Highest level compile function */ Val* Compiler::compile(const goos::Object& code, Env* env) { - auto propagated = try_constant_propagation(code, env); - return compile_no_const_prop(propagated.value, env); + // auto propagated = try_constant_propagation(code, env); + return compile_no_const_prop(code, env); } /*! diff --git a/goalc/compiler/compilation/CompilerControl.cpp b/goalc/compiler/compilation/CompilerControl.cpp index 0bac51418d..2b7bf77244 100644 --- a/goalc/compiler/compilation/CompilerControl.cpp +++ b/goalc/compiler/compilation/CompilerControl.cpp @@ -123,49 +123,37 @@ Val* Compiler::compile_asm_text_file(const goos::Object& form, const goos::Objec Val* Compiler::compile_asm_file(const goos::Object& form, const goos::Object& rest, Env* env) { (void)env; int i = 0; - std::string filename; - std::string disasm_filename = ""; - bool load = false; - bool color = false; - bool write = false; - bool no_code = false; - bool disassemble = false; - bool no_time_prints = false; + CompilationOptions options; bool no_throw = false; - std::vector> timing; - Timer total_timer; - // parse arguments bool last_was_disasm = false; for_each_in_list(rest, [&](const goos::Object& o) { if (last_was_disasm) { last_was_disasm = false; if (o.type == goos::ObjectType::STRING) { - disasm_filename = as_string(o); + options.disassembly_output_file = as_string(o); i++; return; } } if (i == 0) { - filename = as_string(o); + options.filename = as_string(o); } else { auto setting = symbol_string(o); if (setting == ":load") { - load = true; + options.load = true; } else if (setting == ":color") { - color = true; + options.color = true; } else if (setting == ":write") { - write = true; + options.write = true; } else if (setting == ":no-code") { - no_code = true; + options.no_code = true; } else if (setting == ":no-throw") { no_throw = true; } else if (setting == ":disassemble") { - disassemble = true; + options.disassemble = true; last_was_disasm = true; - } else if (setting == ":no-time-prints") { - no_time_prints = true; } else { throw_compiler_error(form, "The option {} was not recognized for asm-file.", setting); } @@ -173,92 +161,8 @@ Val* Compiler::compile_asm_file(const goos::Object& form, const goos::Object& re i++; }); - // READ - Timer reader_timer; try { - auto code = m_goos.reader.read_from_file({filename}); - timing.emplace_back("read", reader_timer.getMs()); - - Timer compile_timer; - std::string obj_file_name = filename; - - // Extract object name from file name. - for (int idx = int(filename.size()) - 1; idx-- > 0;) { - if (filename.at(idx) == '\\' || filename.at(idx) == '/') { - obj_file_name = filename.substr(idx + 1); - break; - } - } - obj_file_name = obj_file_name.substr(0, obj_file_name.find_last_of('.')); - - // COMPILE - auto obj_file = compile_object_file(obj_file_name, code, !no_code); - timing.emplace_back("compile", compile_timer.getMs()); - - if (color) { - // register allocation - Timer color_timer; - color_object_file(obj_file); - timing.emplace_back("color", color_timer.getMs()); - - // code/object file generation - Timer codegen_timer; - std::vector data; - std::string disasm; - if (disassemble) { - codegen_and_disassemble_object_file(obj_file, &data, &disasm); - if (disasm_filename == "") { - printf("%s\n", disasm.c_str()); - } else { - file_util::write_text_file(disasm_filename, disasm); - } - } else { - data = codegen_object_file(obj_file); - } - timing.emplace_back("codegen", codegen_timer.getMs()); - - // send to target - if (load) { - if (m_listener.is_connected()) { - m_listener.send_code(data, obj_file_name); - } else { - printf("WARNING - couldn't load because listener isn't connected\n"); // todo log warn - } - } - - // save file - if (write) { - auto path = file_util::get_file_path({"out", "obj", obj_file_name + ".o"}); - file_util::create_dir_if_needed_for_file(path); - file_util::write_binary_file(path, (void*)data.data(), data.size()); - } - } else { - if (load) { - printf("WARNING - couldn't load because coloring is not enabled\n"); - } - - if (write) { - printf("WARNING - couldn't write because coloring is not enabled\n"); - } - - if (disassemble) { - printf("WARNING - couldn't disassemble because coloring is not enabled\n"); - } - } - - if (m_settings.print_timing) { - printf("F: %36s ", obj_file_name.c_str()); - timing.emplace_back("total", total_timer.getMs()); - for (auto& e : timing) { - printf(" %12s %4.0f", e.first.c_str(), e.second); - } - printf("\n"); - } else { - auto total_time = total_timer.getMs(); - if (total_time > 10.0 && color && !no_time_prints) { - fmt::print("[ASM-FILE] {} took {:.2f} ms\n", obj_file_name, total_time); - } - } + asm_file(options); } catch (std::runtime_error& e) { if (!no_throw) { throw_compiler_error(form, "Error while compiling file: {}", e.what()); diff --git a/goalc/compiler/compilation/Macro.cpp b/goalc/compiler/compilation/Macro.cpp index 3834ca0097..ed68e198e9 100644 --- a/goalc/compiler/compilation/Macro.cpp +++ b/goalc/compiler/compilation/Macro.cpp @@ -267,7 +267,7 @@ bool Compiler::expand_macro_once(const goos::Object& src, goos::Object* out, Env auto goos_result = m_goos.eval_list_return_last(macro->body, macro->body, mac_env); // make the macro expanded form point to the source where the macro was used for error messages. - m_goos.reader.db.inherit_info(src, goos_result); + // m_goos.reader.db.inherit_info(src, goos_result); *out = goos_result; return true; diff --git a/goalc/make/Tools.cpp b/goalc/make/Tools.cpp index b17f6df1e8..75c1d302e3 100644 --- a/goalc/make/Tools.cpp +++ b/goalc/make/Tools.cpp @@ -30,8 +30,11 @@ bool CompilerTool::needs_run(const ToolInput& task) { bool CompilerTool::run(const ToolInput& task) { // todo check inputs try { - m_compiler->run_front_end_on_string( - fmt::format("(asm-file \"{}\" :no-time-prints :color :write)", task.input.at(0))); + CompilationOptions options; + options.filename = task.input.at(0); + options.color = true; + options.write = true; + m_compiler->asm_file(options); } catch (std::exception& e) { fmt::print("Compilation failed: {}\n", e.what()); return false; diff --git a/goalc/regalloc/Allocator_v2.cpp b/goalc/regalloc/Allocator_v2.cpp index 43b948f05a..7865dd4188 100644 --- a/goalc/regalloc/Allocator_v2.cpp +++ b/goalc/regalloc/Allocator_v2.cpp @@ -222,7 +222,7 @@ class VarAssignment { } } - const std::vector live_vector() const { return m_live; } + const std::vector& live_vector() const { return m_live; } private: // common info diff --git a/goalc/regalloc/IRegSet.h b/goalc/regalloc/IRegSet.h index a83b861844..295c3adb6e 100644 --- a/goalc/regalloc/IRegSet.h +++ b/goalc/regalloc/IRegSet.h @@ -20,7 +20,7 @@ class IRegSet { public: - IRegSet() { m_data.reserve(4); } + IRegSet() { resize(64 * 4); } /*! * Add the given ireg to the set.