B3LowerMacrosAfterOptimizations.cpp [plain text]
#include "config.h"
#include "B3LowerMacrosAfterOptimizations.h"
#if ENABLE(B3_JIT)
#include "AirArg.h"
#include "B3BlockInsertionSet.h"
#include "B3CCallValue.h"
#include "B3ConstDoubleValue.h"
#include "B3ConstFloatValue.h"
#include "B3ConstPtrValue.h"
#include "B3InsertionSetInlines.h"
#include "B3PhaseScope.h"
#include "B3ValueInlines.h"
namespace JSC { namespace B3 {
using Arg = Air::Arg;
using Code = Air::Code;
using Tmp = Air::Tmp;
namespace {
class LowerMacrosAfterOptimizations {
public:
LowerMacrosAfterOptimizations(Procedure& proc)
: m_proc(proc)
, m_blockInsertionSet(proc)
, m_insertionSet(proc)
{
}
bool run()
{
for (BasicBlock* block : m_proc) {
m_block = block;
processCurrentBlock();
}
m_changed |= m_blockInsertionSet.execute();
if (m_changed) {
m_proc.resetReachability();
m_proc.invalidateCFG();
}
return m_changed;
}
private:
void processCurrentBlock()
{
for (m_index = 0; m_index < m_block->size(); ++m_index) {
m_value = m_block->at(m_index);
m_origin = m_value->origin();
switch (m_value->opcode()) {
case Abs: {
if (isARM64())
break;
Value* mask = nullptr;
if (m_value->type() == Double)
mask = m_insertionSet.insert<ConstDoubleValue>(m_index, m_origin, bitwise_cast<double>(~(1ll << 63)));
else if (m_value->type() == Float)
mask = m_insertionSet.insert<ConstFloatValue>(m_index, m_origin, bitwise_cast<float>(~(1 << 31)));
else
RELEASE_ASSERT_NOT_REACHED();
Value* result = m_insertionSet.insert<Value>(m_index, BitAnd, m_origin, m_value->child(0), mask);
m_value->replaceWithIdentity(result);
break;
}
case Ceil: {
if (MacroAssembler::supportsFloatingPointRounding())
break;
Value* functionAddress = nullptr;
if (m_value->type() == Double)
functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, tagCFunction<OperationPtrTag>(Math::ceilDouble));
else if (m_value->type() == Float)
functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, tagCFunction<OperationPtrTag>(Math::ceilFloat));
else
RELEASE_ASSERT_NOT_REACHED();
Value* result = m_insertionSet.insert<CCallValue>(m_index,
m_value->type(),
m_origin,
Effects::none(),
functionAddress,
m_value->child(0));
m_value->replaceWithIdentity(result);
break;
}
case Floor: {
if (MacroAssembler::supportsFloatingPointRounding())
break;
Value* functionAddress = nullptr;
if (m_value->type() == Double)
functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, tagCFunction<OperationPtrTag>(Math::floorDouble));
else if (m_value->type() == Float)
functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, tagCFunction<OperationPtrTag>(Math::floorFloat));
else
RELEASE_ASSERT_NOT_REACHED();
Value* result = m_insertionSet.insert<CCallValue>(m_index,
m_value->type(),
m_origin,
Effects::none(),
functionAddress,
m_value->child(0));
m_value->replaceWithIdentity(result);
break;
}
case Neg: {
if (!m_value->type().isFloat())
break;
if (!isX86())
break;
Value* mask = nullptr;
if (m_value->type() == Double)
mask = m_insertionSet.insert<ConstDoubleValue>(m_index, m_origin, -0.0);
else {
RELEASE_ASSERT(m_value->type() == Float);
mask = m_insertionSet.insert<ConstFloatValue>(m_index, m_origin, -0.0f);
}
Value* result = m_insertionSet.insert<Value>(
m_index, BitXor, m_origin, m_value->child(0), mask);
m_value->replaceWithIdentity(result);
break;
}
case RotL: {
if (isARM64()) {
Value* newShift = m_insertionSet.insert<Value>(m_index, Neg, m_value->origin(), m_value->child(1));
Value* rotate = m_insertionSet.insert<Value>(m_index, RotR, m_value->origin(), m_value->child(0), newShift);
m_value->replaceWithIdentity(rotate);
break;
}
break;
}
default:
break;
}
}
m_insertionSet.execute(m_block);
}
Procedure& m_proc;
BlockInsertionSet m_blockInsertionSet;
InsertionSet m_insertionSet;
BasicBlock* m_block;
unsigned m_index;
Value* m_value;
Origin m_origin;
bool m_changed { false };
};
bool lowerMacrosImpl(Procedure& proc)
{
LowerMacrosAfterOptimizations lowerMacros(proc);
return lowerMacros.run();
}
}
bool lowerMacrosAfterOptimizations(Procedure& proc)
{
PhaseScope phaseScope(proc, "lowerMacrosAfterOptimizations");
bool result = lowerMacrosImpl(proc);
if (shouldValidateIR())
RELEASE_ASSERT(!lowerMacrosImpl(proc));
return result;
}
} }
#endif // ENABLE(B3_JIT)