LLVM: Try to reuse BitCasts

This commit is contained in:
Elad 2026-03-16 08:18:53 +02:00
parent e83034624b
commit 9a0a5a1735
2 changed files with 57 additions and 3 deletions

View File

@ -225,12 +225,66 @@ llvm::Value* cpu_translator::bitcast(llvm::Value* val, llvm::Type* type) const
fmt::throw_exception("cpu_translator::bitcast(): incompatible type sizes (%u vs %u)", s1, s2);
}
if (const auto c1 = llvm::dyn_cast<llvm::Constant>(val))
if (val->getType() == type)
{
return val;
}
llvm::CastInst* i;
llvm::Value* source_val = val;
// Try to reuse older bitcasts
while ((i = llvm::dyn_cast_or_null<llvm::CastInst>(source_val)) && i->getOpcode() == llvm::Instruction::BitCast)
{
source_val = i->getOperand(0);
if (source_val->getType() == type)
{
return source_val;
}
}
for (auto it = source_val->use_begin(); it != source_val->use_end(); ++it)
{
llvm::Value* it_val = *it;
if (!it_val)
{
continue;
}
llvm::CastInst* bci = llvm::dyn_cast_or_null<llvm::CastInst>(it_val);
// Walk through bitcasts
while (bci && bci->getOpcode() == llvm::Instruction::BitCast)
{
if (bci->getParent() != m_ir->GetInsertBlock())
{
break;
}
if (bci->getType() == type)
{
return bci;
}
if (bci->use_begin() == bci->use_end())
{
break;
}
bci = llvm::dyn_cast_or_null<llvm::CastInst>(*bci->use_begin());
}
}
// Do bitcast on the source
if (const auto c1 = llvm::dyn_cast<llvm::Constant>(source_val))
{
return ensure(llvm::ConstantFoldCastOperand(llvm::Instruction::BitCast, c1, type, m_module->getDataLayout()));
}
return m_ir->CreateBitCast(val, type);
return m_ir->CreateBitCast(source_val, type);
}
template <>

View File

@ -991,7 +991,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
}
// Write register to the context
_store = m_ir->CreateStore(is_xfloat ? double_to_xfloat(saved_value) : m_ir->CreateBitCast(value, get_reg_type(index)), addr);
_store = m_ir->CreateStore(is_xfloat ? double_to_xfloat(saved_value) : bitcast(value, get_reg_type(index)), addr);
spu_context_attr(_store);
}