Skip to content

Commit

Permalink
ir: more aggressively reuse const floats
Browse files Browse the repository at this point in the history
Signed-off-by: Wolfgang Bumiller <[email protected]>
Closes #202
  • Loading branch information
Blub committed May 5, 2023
1 parent 111eef7 commit 2fe0af0
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
1 change: 1 addition & 0 deletions gmqcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <string>
#include <utility>
#include <memory>
#include <map>
using std::move;
#include <stdarg.h>
#include <stddef.h>
Expand Down
44 changes: 42 additions & 2 deletions ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3300,6 +3300,41 @@ static void gen_vector_fields(code_t *code, prog_section_field_t fld, const char
mem_d(component);
}

// Check if the value can be reused from a previous value. If so, copy the
// `m_code` segment and return `true`. Othrewise return false and, if the value
// is eligable to be reused later, record it in `m_reusable_const_floats`.
bool ir_builder::generateMergedFloat(ir_value *global, bool register_only)
{
if ((global->m_flags & IR_FLAG_INCLUDE_DEF)
|| global->m_callparam || global->m_locked || global->m_unique_life
|| global->m_memberof
|| global->m_members[0]
|| global->m_members[1]
|| global->m_members[2]
|| global->m_store != store_global
)
{
return false;
}

if (!global->m_writes.empty()) {
irerror(global->m_context, "writing to a global const");
return false;
}

auto old = m_reusable_const_floats.find(global->m_constval.vint);
if (old == m_reusable_const_floats.end()) {
auto iptr = (int32_t*)&global->m_constval.ivec[0];
m_reusable_const_floats[*iptr] = global;
return false;
} else if (register_only) {
return false;
} else {
global->m_code = old->second->m_code;
return true;
}
}

bool ir_builder::generateGlobal(ir_value *global, bool islocal)
{
size_t i;
Expand Down Expand Up @@ -3401,8 +3436,13 @@ bool ir_builder::generateGlobal(ir_value *global, bool islocal)
{
global->setCodeAddress(m_code->globals.size());
if (global->m_hasvalue) {
if (global->m_cvq == CV_CONST && global->m_reads.empty())
return true;
if (global->m_cvq == CV_CONST) {
if (global->m_reads.empty())
return true;

if (!islocal && generateMergedFloat(global, pushdef))
return global->m_code.globaladdr >= 0;
}
iptr = (int32_t*)&global->m_constval.ivec[0];
m_code->globals.push_back(*iptr);
} else {
Expand Down
2 changes: 2 additions & 0 deletions ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ struct ir_builder {
std::vector<std::unique_ptr<ir_value>> m_fields;
// for reusing them in vector-splits, TODO: sort this or use a radix-tree
std::vector<ir_value*> m_const_floats;
std::map<int32_t, ir_value*> m_reusable_const_floats;

ht m_htfunctions;
ht m_htglobals;
Expand Down Expand Up @@ -313,6 +314,7 @@ struct ir_builder {
bool generateGlobalFunction(ir_value*);
bool generateGlobalFunctionCode(ir_value*);
bool generateFunctionLocals(ir_value*);
bool generateMergedFloat(ir_value*, bool register_only);
};

/*
Expand Down

0 comments on commit 2fe0af0

Please sign in to comment.