Commit 572196f6 authored by dcarney's avatar dcarney Committed by Commit bot

[turbofan] support small immediates

R=titzer@chromium.org

BUG=

Review URL: https://codereview.chromium.org/1075903002

Cr-Commit-Position: refs/heads/master@{#27709}
parent 5d56277e
......@@ -100,7 +100,7 @@ class InstructionOperandConverter {
Constant ToConstant(InstructionOperand* op) {
if (op->IsImmediate()) {
return gen_->code()->GetImmediate(ImmediateOperand::cast(op)->index());
return gen_->code()->GetImmediate(ImmediateOperand::cast(op));
}
return gen_->code()->GetConstant(
ConstantOperand::cast(op)->virtual_register());
......
......@@ -119,8 +119,7 @@ class OperandGenerator {
}
InstructionOperand UseImmediate(Node* node) {
int index = sequence()->AddImmediate(ToConstant(node));
return ImmediateOperand(index);
return sequence()->AddImmediate(ToConstant(node));
}
InstructionOperand UseLocation(Node* node, LinkageLocation location,
......@@ -149,8 +148,7 @@ class OperandGenerator {
}
InstructionOperand TempImmediate(int32_t imm) {
int index = sequence()->AddImmediate(Constant(imm));
return ImmediateOperand(index);
return sequence()->AddImmediate(Constant(imm));
}
InstructionOperand TempLocation(LinkageLocation location, MachineType type) {
......@@ -159,9 +157,8 @@ class OperandGenerator {
}
InstructionOperand Label(BasicBlock* block) {
int index = sequence()->AddImmediate(
return sequence()->AddImmediate(
Constant(RpoNumber::FromInt(block->rpo_number())));
return ImmediateOperand(index);
}
protected:
......
......@@ -44,8 +44,15 @@ std::ostream& operator<<(std::ostream& os,
case InstructionOperand::CONSTANT:
return os << "[constant:" << ConstantOperand::cast(op).virtual_register()
<< "]";
case InstructionOperand::IMMEDIATE:
return os << "[immediate:" << ImmediateOperand::cast(op).index() << "]";
case InstructionOperand::IMMEDIATE: {
auto imm = ImmediateOperand::cast(op);
switch (imm.type()) {
case ImmediateOperand::INLINE:
return os << "#" << imm.inline_value();
case ImmediateOperand::INDEXED:
return os << "[immediate:" << imm.indexed_value() << "]";
}
}
case InstructionOperand::ALLOCATED:
switch (AllocatedOperand::cast(op).allocated_kind()) {
case AllocatedOperand::STACK_SLOT:
......@@ -606,7 +613,7 @@ RpoNumber InstructionSequence::InputRpo(Instruction* instr, size_t index) {
InstructionOperand* operand = instr->InputAt(index);
Constant constant =
operand->IsImmediate()
? GetImmediate(ImmediateOperand::cast(operand)->index())
? GetImmediate(ImmediateOperand::cast(operand))
: GetConstant(ConstantOperand::cast(operand)->virtual_register());
return constant.ToRpoNumber();
}
......
......@@ -317,22 +317,35 @@ class ConstantOperand : public InstructionOperand {
class ImmediateOperand : public InstructionOperand {
public:
explicit ImmediateOperand(int index) : InstructionOperand(IMMEDIATE) {
value_ |= static_cast<int64_t>(index) << IndexField::kShift;
enum ImmediateType { INLINE, INDEXED };
explicit ImmediateOperand(ImmediateType type, int32_t value)
: InstructionOperand(IMMEDIATE) {
value_ |= TypeField::encode(type);
value_ |= static_cast<int64_t>(value) << ValueField::kShift;
}
int index() const {
return static_cast<int64_t>(value_) >> IndexField::kShift;
ImmediateType type() const { return TypeField::decode(value_); }
int32_t inline_value() const {
DCHECK_EQ(INLINE, type());
return static_cast<int64_t>(value_) >> ValueField::kShift;
}
int32_t indexed_value() const {
DCHECK_EQ(INDEXED, type());
return static_cast<int64_t>(value_) >> ValueField::kShift;
}
static ImmediateOperand* New(Zone* zone, int index) {
return InstructionOperand::New(zone, ImmediateOperand(index));
static ImmediateOperand* New(Zone* zone, ImmediateType type, int32_t value) {
return InstructionOperand::New(zone, ImmediateOperand(type, value));
}
INSTRUCTION_OPERAND_CASTS(ImmediateOperand, IMMEDIATE);
STATIC_ASSERT(KindField::kSize == 3);
class IndexField : public BitField64<int32_t, 35, 29> {};
class TypeField : public BitField64<ImmediateType, 3, 1> {};
class ValueField : public BitField64<int32_t, 32, 32> {};
};
......@@ -1066,15 +1079,28 @@ class InstructionSequence FINAL : public ZoneObject {
typedef ZoneVector<Constant> Immediates;
Immediates& immediates() { return immediates_; }
int AddImmediate(Constant constant) {
ImmediateOperand AddImmediate(const Constant& constant) {
if (constant.type() == Constant::kInt32) {
return ImmediateOperand(ImmediateOperand::INLINE, constant.ToInt32());
}
int index = static_cast<int>(immediates_.size());
immediates_.push_back(constant);
return index;
}
Constant GetImmediate(int index) const {
DCHECK(index >= 0);
DCHECK(index < static_cast<int>(immediates_.size()));
return immediates_[index];
return ImmediateOperand(ImmediateOperand::INDEXED, index);
}
Constant GetImmediate(const ImmediateOperand* op) const {
switch (op->type()) {
case ImmediateOperand::INLINE:
return Constant(op->inline_value());
case ImmediateOperand::INDEXED: {
int index = op->indexed_value();
DCHECK(index >= 0);
DCHECK(index < static_cast<int>(immediates_.size()));
return immediates_[index];
}
}
UNREACHABLE();
return Constant(static_cast<int32_t>(0));
}
class StateId {
......
......@@ -122,8 +122,11 @@ void RegisterAllocatorVerifier::BuildConstraint(const InstructionOperand* op,
constraint->value_ = ConstantOperand::cast(op)->virtual_register();
constraint->virtual_register_ = constraint->value_;
} else if (op->IsImmediate()) {
auto imm = ImmediateOperand::cast(op);
int value = imm->type() == ImmediateOperand::INLINE ? imm->inline_value()
: imm->indexed_value();
constraint->type_ = kImmediate;
constraint->value_ = ImmediateOperand::cast(op)->index();
constraint->value_ = value;
} else {
CHECK(op->IsUnallocated());
const auto* unallocated = UnallocatedOperand::cast(op);
......@@ -183,10 +186,15 @@ void RegisterAllocatorVerifier::CheckConstraint(
CHECK_EQ(ConstantOperand::cast(op)->virtual_register(),
constraint->value_);
return;
case kImmediate:
case kImmediate: {
CHECK(op->IsImmediate());
CHECK_EQ(ImmediateOperand::cast(op)->index(), constraint->value_);
auto imm = ImmediateOperand::cast(op);
int value = imm->type() == ImmediateOperand::INLINE
? imm->inline_value()
: imm->indexed_value();
CHECK_EQ(value, constraint->value_);
return;
}
case kRegister:
CHECK(op->IsRegister());
return;
......
......@@ -66,7 +66,7 @@ class TestCode : public HandleAndZoneScope {
Start();
sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop));
int index = static_cast<int>(sequence_.instructions().size()) - 1;
AddGapMove(index, ImmediateOperand::New(main_zone(), 11),
AddGapMove(index, ConstantOperand::New(main_zone(), 11),
RegisterOperand::New(main_zone(), 11));
}
void Other() {
......@@ -80,8 +80,7 @@ class TestCode : public HandleAndZoneScope {
rpo_number_ = RpoNumber::FromInt(rpo_number_.ToInt() + 1);
}
InstructionOperand UseRpo(int num) {
int index = sequence_.AddImmediate(Constant(RpoNumber::FromInt(num)));
return ImmediateOperand(index);
return sequence_.AddImmediate(Constant(RpoNumber::FromInt(num)));
}
void Start(bool deferred = false) {
if (current_ == NULL) {
......
......@@ -84,9 +84,12 @@ InstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build(
InstructionOperand* input = instr->InputAt(i);
EXPECT_NE(InstructionOperand::CONSTANT, input->kind());
if (input->IsImmediate()) {
int index = ImmediateOperand::cast(input)->index();
s.immediates_.insert(
std::make_pair(index, sequence.GetImmediate(index)));
auto imm = ImmediateOperand::cast(input);
if (imm->type() == ImmediateOperand::INDEXED) {
int index = imm->indexed_value();
s.immediates_.insert(
std::make_pair(index, sequence.GetImmediate(imm)));
}
}
}
s.instructions_.push_back(instr);
......
......@@ -209,8 +209,12 @@ class InstructionSelectorTest : public TestWithContext,
EXPECT_FALSE(constants_.end() == i);
} else {
EXPECT_EQ(InstructionOperand::IMMEDIATE, operand->kind());
i = immediates_.find(ImmediateOperand::cast(operand)->index());
EXPECT_EQ(ImmediateOperand::cast(operand)->index(), i->first);
auto imm = ImmediateOperand::cast(operand);
if (imm->type() == ImmediateOperand::INLINE) {
return Constant(imm->inline_value());
}
i = immediates_.find(imm->indexed_value());
EXPECT_EQ(imm->indexed_value(), i->first);
EXPECT_FALSE(immediates_.end() == i);
}
return i->second;
......
......@@ -129,8 +129,7 @@ Instruction* InstructionSequenceTest::EndBlock(BlockCompletion completion) {
InstructionSequenceTest::TestOperand InstructionSequenceTest::Imm(int32_t imm) {
int index = sequence()->AddImmediate(Constant(imm));
return TestOperand(kImmediate, index);
return TestOperand(kImmediate, imm);
}
......@@ -357,7 +356,7 @@ InstructionOperand* InstructionSequenceTest::ConvertInputs(
InstructionOperand InstructionSequenceTest::ConvertInputOp(TestOperand op) {
if (op.type_ == kImmediate) {
CHECK_EQ(op.vreg_.value_, kNoValue);
return ImmediateOperand(op.value_);
return ImmediateOperand(ImmediateOperand::INLINE, op.value_);
}
CHECK_NE(op.vreg_.value_, kNoValue);
switch (op.type_) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment