#include "config.h"
#include "AirCode.h"
#if ENABLE(B3_JIT)
#include "AirCCallSpecial.h"
#include "B3BasicBlockUtils.h"
#include "B3StackSlot.h"
namespace JSC { namespace B3 { namespace Air {
Code::Code(Procedure& proc)
: m_proc(proc)
, m_lastPhaseName("initial")
{
}
Code::~Code()
{
}
BasicBlock* Code::addBlock(double frequency)
{
std::unique_ptr<BasicBlock> block(new BasicBlock(m_blocks.size(), frequency));
BasicBlock* result = block.get();
m_blocks.append(WTFMove(block));
return result;
}
StackSlot* Code::addStackSlot(unsigned byteSize, StackSlotKind kind, B3::StackSlot* b3Slot)
{
return m_stackSlots.addNew(byteSize, kind, b3Slot);
}
StackSlot* Code::addStackSlot(B3::StackSlot* b3Slot)
{
return addStackSlot(b3Slot->byteSize(), StackSlotKind::Locked, b3Slot);
}
Special* Code::addSpecial(std::unique_ptr<Special> special)
{
special->m_code = this;
return m_specials.add(WTFMove(special));
}
CCallSpecial* Code::cCallSpecial()
{
if (!m_cCallSpecial) {
m_cCallSpecial = static_cast<CCallSpecial*>(
addSpecial(std::make_unique<CCallSpecial>()));
}
return m_cCallSpecial;
}
void Code::resetReachability()
{
recomputePredecessors(m_blocks);
for (auto& block : m_blocks) {
if (isBlockDead(block.get()))
block = nullptr;
}
}
void Code::dump(PrintStream& out) const
{
for (BasicBlock* block : *this)
out.print(deepDump(block));
if (stackSlots().size()) {
out.print("Stack slots:\n");
for (StackSlot* slot : stackSlots())
out.print(" ", pointerDump(slot), ": ", deepDump(slot), "\n");
}
if (specials().size()) {
out.print("Specials:\n");
for (Special* special : specials())
out.print(" ", deepDump(special), "\n");
}
if (m_frameSize)
out.print("Frame size: ", m_frameSize, "\n");
if (m_callArgAreaSize)
out.print("Call arg area size: ", m_callArgAreaSize, "\n");
if (m_calleeSaveRegisters.size())
out.print("Callee saves: ", m_calleeSaveRegisters, "\n");
}
unsigned Code::findFirstBlockIndex(unsigned index) const
{
while (index < size() && !at(index))
index++;
return index;
}
unsigned Code::findNextBlockIndex(unsigned index) const
{
return findFirstBlockIndex(index + 1);
}
BasicBlock* Code::findNextBlock(BasicBlock* block) const
{
unsigned index = findNextBlockIndex(block->index());
if (index < size())
return at(index);
return nullptr;
}
void Code::addFastTmp(Tmp tmp)
{
m_fastTmps.add(tmp);
}
unsigned Code::jsHash() const
{
unsigned result = 0;
for (BasicBlock* block : *this) {
result *= 1000001;
for (Inst& inst : *block) {
result *= 97;
result += inst.jsHash();
}
for (BasicBlock* successor : block->successorBlocks()) {
result *= 7;
result += successor->index();
}
}
for (StackSlot* slot : stackSlots()) {
result *= 101;
result += slot->jsHash();
}
return result;
}
} } }
#endif // ENABLE(B3_JIT)