Bug 1010586 - IonMonkey: Shrink the MUse class by making the index field unnecessary. r=nbp

This commit is contained in:
Dan Gohman 2014-05-20 18:43:15 -07:00
parent 9f78dc2ea0
commit 439e296431
6 changed files with 119 additions and 43 deletions

View File

@ -45,7 +45,7 @@ AnalyzeLsh(TempAllocator &alloc, MLsh *lsh)
if (add->specialization() != MIRType_Int32 || !add->isTruncated())
break;
MDefinition *other = add->getOperand(1 - use->index());
MDefinition *other = add->getOperand(1 - add->indexOf(*use));
if (other->isConstant()) {
displacement += other->toConstant()->value().toInt32();
@ -71,7 +71,7 @@ AnalyzeLsh(TempAllocator &alloc, MLsh *lsh)
return;
MBitAnd *bitAnd = use->consumer()->toDefinition()->toBitAnd();
MDefinition *other = bitAnd->getOperand(1 - use->index());
MDefinition *other = bitAnd->getOperand(1 - bitAnd->indexOf(*use));
if (!other->isConstant() || !other->toConstant()->value().isInt32())
return;

View File

@ -2559,7 +2559,7 @@ jit::AnalyzeArgumentsUsage(JSContext *cx, JSScript *scriptArg)
if (!use->isInstruction())
return true;
if (!ArgumentsUseCanBeLazy(cx, script, use->toInstruction(), uses.index(),
if (!ArgumentsUseCanBeLazy(cx, script, use->toInstruction(), use->indexOf(uses.use()),
&argumentsContentsObserved))
{
return true;

View File

@ -1951,15 +1951,19 @@ MustCloneRegExp(MRegExp *regexp)
return true;
MDefinition *def = node->toDefinition();
if (def->isRegExpTest() && iter->index() == 1) {
// Optimized RegExp.prototype.test.
JS_ASSERT(def->toRegExpTest()->regexp() == regexp);
continue;
if (def->isRegExpTest()) {
MRegExpTest *test = def->toRegExpTest();
if (test->indexOf(*iter) == 1) {
// Optimized RegExp.prototype.test.
JS_ASSERT(test->regexp() == regexp);
continue;
}
} else if (def->isCall()) {
MCall *call = def->toCall();
if (!MustCloneRegExpForCall(call, call->indexOf(*iter)))
continue;
}
if (def->isCall() && !MustCloneRegExpForCall(def->toCall(), iter->index()))
continue;
return true;
}
return false;

View File

@ -30,6 +30,11 @@ using mozilla::NumbersAreIdentical;
using mozilla::IsFloat32Representable;
using mozilla::Maybe;
size_t MUse::index() const
{
return consumer()->indexOf(this);
}
template<size_t Op> static void
ConvertDefinitionToDouble(TempAllocator &alloc, MDefinition *def, MInstruction *consumer)
{
@ -393,7 +398,6 @@ MNode::replaceOperand(MUseIterator use, MDefinition *def)
uint32_t index = use->index();
MDefinition *prev = use->producer();
JS_ASSERT(use->index() < numOperands());
JS_ASSERT(use->producer() == getOperand(index));
JS_ASSERT(use->consumer() == this);
@ -413,7 +417,6 @@ MNode::replaceOperand(size_t index, MDefinition *def)
MDefinition *prev = use->producer();
JS_ASSERT(use->index() == index);
JS_ASSERT(use->index() < numOperands());
JS_ASSERT(use->producer() == getOperand(index));
JS_ASSERT(use->consumer() == this);
@ -437,7 +440,7 @@ MNode::discardOperand(size_t index)
#ifdef DEBUG
// Causes any producer/consumer lookups to trip asserts.
use->set(nullptr, nullptr, index);
use->set(nullptr, nullptr);
#endif
}

View File

@ -115,25 +115,22 @@ class MUse : public TempObject, public InlineListNode<MUse>
MDefinition *producer_; // MDefinition that is being used.
MNode *consumer_; // The node that is using this operand.
uint32_t index_; // The index of this operand in its consumer.
MUse(MDefinition *producer, MNode *consumer, uint32_t index)
MUse(MDefinition *producer, MNode *consumer)
: producer_(producer),
consumer_(consumer),
index_(index)
consumer_(consumer)
{ }
public:
// Default constructor for use in vectors.
MUse()
: producer_(nullptr), consumer_(nullptr), index_(0)
: producer_(nullptr), consumer_(nullptr)
{ }
// Set data inside the MUse.
void set(MDefinition *producer, MNode *consumer, uint32_t index) {
void set(MDefinition *producer, MNode *consumer) {
producer_ = producer;
consumer_ = consumer;
index_ = index;
}
MDefinition *producer() const {
@ -147,9 +144,11 @@ class MUse : public TempObject, public InlineListNode<MUse>
JS_ASSERT(consumer_ != nullptr);
return consumer_;
}
uint32_t index() const {
return index_;
}
// Return the operand index of this MUse in its consumer. In general,
// code should prefer to call indexOf on the casted consumer directly,
// to allow it to be devirtualized and inlined.
size_t index() const;
};
typedef InlineList<MUse>::iterator MUseIterator;
@ -187,6 +186,7 @@ class MNode : public TempObject
// Returns the definition at a given operand.
virtual MDefinition *getOperand(size_t index) const = 0;
virtual size_t numOperands() const = 0;
virtual size_t indexOf(const MUse *u) const = 0;
bool isDefinition() const {
return kind() == Definition;
@ -228,6 +228,7 @@ class MNode : public TempObject
// Gets the MUse corresponding to given operand.
virtual MUse *getUseFor(size_t index) = 0;
virtual const MUse *getUseFor(size_t index) const = 0;
};
class AliasSet {
@ -739,9 +740,6 @@ class MUseDefIterator
MDefinition *def() const {
return current_->consumer()->toDefinition();
}
size_t index() const {
return current_->index();
}
};
// An instruction is an SSA name that is inserted into a basic block's IR
@ -786,7 +784,7 @@ class MAryInstruction : public MInstruction
mozilla::Array<MUse, Arity> operands_;
void setOperand(size_t index, MDefinition *operand) MOZ_FINAL MOZ_OVERRIDE {
operands_[index].set(operand, this, index);
operands_[index].set(operand, this);
operand->addUse(&operands_[index]);
}
@ -794,6 +792,10 @@ class MAryInstruction : public MInstruction
return &operands_[index];
}
const MUse *getUseFor(size_t index) const MOZ_FINAL MOZ_OVERRIDE {
return &operands_[index];
}
public:
MDefinition *getOperand(size_t index) const MOZ_FINAL MOZ_OVERRIDE {
return operands_[index].producer();
@ -801,6 +803,11 @@ class MAryInstruction : public MInstruction
size_t numOperands() const MOZ_FINAL MOZ_OVERRIDE {
return Arity;
}
size_t indexOf(const MUse *u) const MOZ_FINAL MOZ_OVERRIDE {
MOZ_ASSERT(u >= &operands_[0]);
MOZ_ASSERT(u <= &operands_[numOperands() - 1]);
return u - &operands_[0];
}
};
class MNullaryInstruction : public MAryInstruction<0>
@ -1174,7 +1181,7 @@ class MTableSwitch MOZ_FINAL
protected:
void setOperand(size_t index, MDefinition *operand) {
JS_ASSERT(index == 0);
operand_.set(operand, this, index);
operand_.set(operand, this);
operand->addUse(&operand_);
}
@ -1183,6 +1190,11 @@ class MTableSwitch MOZ_FINAL
return &operand_;
}
const MUse *getUseFor(size_t index) const {
JS_ASSERT(index == 0);
return &operand_;
}
public:
INSTRUCTION_HEADER(TableSwitch)
static MTableSwitch *New(TempAllocator &alloc, MDefinition *ins, int32_t low, int32_t high);
@ -1264,6 +1276,11 @@ class MTableSwitch MOZ_FINAL
return 1;
}
size_t indexOf(const MUse *u) const MOZ_FINAL MOZ_OVERRIDE {
MOZ_ASSERT(u == getUseFor(0));
return 0;
}
TypePolicy *typePolicy() {
return this;
}
@ -1277,7 +1294,7 @@ class MAryControlInstruction : public MControlInstruction
protected:
void setOperand(size_t index, MDefinition *operand) MOZ_FINAL MOZ_OVERRIDE {
operands_[index].set(operand, this, index);
operands_[index].set(operand, this);
operand->addUse(&operands_[index]);
}
void setSuccessor(size_t index, MBasicBlock *successor) {
@ -1288,6 +1305,10 @@ class MAryControlInstruction : public MControlInstruction
return &operands_[index];
}
const MUse *getUseFor(size_t index) const MOZ_FINAL MOZ_OVERRIDE {
return &operands_[index];
}
public:
MDefinition *getOperand(size_t index) const MOZ_FINAL MOZ_OVERRIDE {
return operands_[index].producer();
@ -1295,6 +1316,11 @@ class MAryControlInstruction : public MControlInstruction
size_t numOperands() const MOZ_FINAL MOZ_OVERRIDE {
return Arity;
}
size_t indexOf(const MUse *u) const MOZ_FINAL MOZ_OVERRIDE {
MOZ_ASSERT(u >= &operands_[0]);
MOZ_ASSERT(u <= &operands_[numOperands() - 1]);
return u - &operands_[0];
}
size_t numSuccessors() const MOZ_FINAL MOZ_OVERRIDE {
return Successors;
}
@ -1906,14 +1932,23 @@ class MVariadicInstruction : public MInstruction
size_t numOperands() const MOZ_FINAL MOZ_OVERRIDE {
return operands_.length();
}
size_t indexOf(const MUse *u) const MOZ_FINAL MOZ_OVERRIDE {
MOZ_ASSERT(u >= &operands_[0]);
MOZ_ASSERT(u <= &operands_[numOperands() - 1]);
return u - &operands_[0];
}
void setOperand(size_t index, MDefinition *operand) MOZ_FINAL MOZ_OVERRIDE {
operands_[index].set(operand, this, index);
operands_[index].set(operand, this);
operand->addUse(&operands_[index]);
}
MUse *getUseFor(size_t index) MOZ_FINAL MOZ_OVERRIDE {
return &operands_[index];
}
const MUse *getUseFor(size_t index) const MOZ_FINAL MOZ_OVERRIDE {
return &operands_[index];
}
};
class MCall
@ -4713,6 +4748,9 @@ class MPhi MOZ_FINAL : public MDefinition, public InlineForwardListNode<MPhi>
MUse *getUseFor(size_t index) {
return &inputs_[index];
}
const MUse *getUseFor(size_t index) const {
return &inputs_[index];
}
public:
INSTRUCTION_HEADER(Phi)
@ -4742,7 +4780,7 @@ class MPhi MOZ_FINAL : public MDefinition, public InlineForwardListNode<MPhi>
// operands. This can arise during e.g. value numbering, where
// definitions producing the same value may have different type sets.
JS_ASSERT(index < numOperands());
inputs_[index].set(operand, this, index);
inputs_[index].set(operand, this);
operand->addUse(&inputs_[index]);
}
@ -4754,6 +4792,11 @@ class MPhi MOZ_FINAL : public MDefinition, public InlineForwardListNode<MPhi>
size_t numOperands() const {
return inputs_.length();
}
size_t indexOf(const MUse *u) const MOZ_FINAL MOZ_OVERRIDE {
MOZ_ASSERT(u >= &inputs_[0]);
MOZ_ASSERT(u <= &inputs_[numOperands() - 1]);
return u - &inputs_[0];
}
bool hasBackedgeType() const {
return hasBackedgeType_;
}
@ -6722,7 +6765,7 @@ class MStoreTypedArrayElement
TruncateKind operandTruncateKind(size_t index) const;
bool canConsumeFloat32(MUse *use) const {
return use->index() == 2 && arrayType_ == ScalarTypeDescr::TYPE_FLOAT32;
return use == getUseFor(2) && arrayType_ == ScalarTypeDescr::TYPE_FLOAT32;
}
};
@ -6790,7 +6833,7 @@ class MStoreTypedArrayElementHole
TruncateKind operandTruncateKind(size_t index) const;
bool canConsumeFloat32(MUse *use) const {
return use->index() == 3 && arrayType_ == ScalarTypeDescr::TYPE_FLOAT32;
return use == getUseFor(3) && arrayType_ == ScalarTypeDescr::TYPE_FLOAT32;
}
};
@ -6837,7 +6880,7 @@ class MStoreTypedArrayElementStatic :
TruncateKind operandTruncateKind(size_t index) const;
bool canConsumeFloat32(MUse *use) const {
return use->index() == 1 && typedArray_->type() == ScalarTypeDescr::TYPE_FLOAT32;
return use == getUseFor(1) && typedArray_->type() == ScalarTypeDescr::TYPE_FLOAT32;
}
};
@ -7348,13 +7391,17 @@ class MDispatchInstruction
protected:
void setOperand(size_t index, MDefinition *operand) MOZ_FINAL MOZ_OVERRIDE {
JS_ASSERT(index == 0);
operand_.set(operand, this, 0);
operand_.set(operand, this);
operand->addUse(&operand_);
}
MUse *getUseFor(size_t index) MOZ_FINAL MOZ_OVERRIDE {
JS_ASSERT(index == 0);
return &operand_;
}
const MUse *getUseFor(size_t index) const MOZ_FINAL MOZ_OVERRIDE {
JS_ASSERT(index == 0);
return &operand_;
}
MDefinition *getOperand(size_t index) const MOZ_FINAL MOZ_OVERRIDE {
JS_ASSERT(index == 0);
return operand_.producer();
@ -7362,6 +7409,10 @@ class MDispatchInstruction
size_t numOperands() const MOZ_FINAL MOZ_OVERRIDE {
return 1;
}
size_t indexOf(const MUse *u) const MOZ_FINAL MOZ_OVERRIDE {
JS_ASSERT(u == getUseFor(0));
return 0;
}
public:
void setSuccessor(size_t i, MBasicBlock *successor) {
@ -8299,7 +8350,7 @@ class MSetElementCache
return this;
}
bool canConsumeFloat32(MUse *use) const { return use->index() == 2; }
bool canConsumeFloat32(MUse *use) const { return use == getUseFor(2); }
};
class MCallGetProperty
@ -9406,7 +9457,7 @@ class MPostWriteBarrier : public MBinaryInstruction, public ObjectPolicy<0>
bool isConsistentFloat32Use(MUse *use) const {
// During lowering, values that neither have object nor value MIR type
// are ignored, thus Float32 can show up at this point without any issue.
return use->index() == 1;
return use == getUseFor(1);
}
#endif
};
@ -9700,7 +9751,7 @@ class MResumePoint MOZ_FINAL : public MNode, public InlineForwardListNode<MResum
JS_ASSERT(index < stackDepth_);
// Note: We do not remove the isObserved flag, as this would imply that
// we check the list of uses of the removed MDefinition.
operands_[index].set(operand, this, index);
operands_[index].set(operand, this);
operand->addUse(&operands_[index]);
if (!operand->isObserved() && isObservableOperand(index))
operand->setObserved();
@ -9708,12 +9759,15 @@ class MResumePoint MOZ_FINAL : public MNode, public InlineForwardListNode<MResum
void clearOperand(size_t index) {
JS_ASSERT(index < stackDepth_);
operands_[index].set(nullptr, this, index);
operands_[index].set(nullptr, this);
}
MUse *getUseFor(size_t index) {
return &operands_[index];
}
const MUse *getUseFor(size_t index) const {
return &operands_[index];
}
public:
static MResumePoint *New(TempAllocator &alloc, MBasicBlock *block, jsbytecode *pc,
@ -9725,6 +9779,11 @@ class MResumePoint MOZ_FINAL : public MNode, public InlineForwardListNode<MResum
size_t numOperands() const {
return stackDepth_;
}
size_t indexOf(const MUse *u) const MOZ_FINAL MOZ_OVERRIDE {
MOZ_ASSERT(u >= &operands_[0]);
MOZ_ASSERT(u <= &operands_[numOperands() - 1]);
return u - &operands_[0];
}
bool isObservableOperand(size_t index) const;
@ -10197,12 +10256,15 @@ class MAsmJSCall MOZ_FINAL : public MInstruction
protected:
void setOperand(size_t index, MDefinition *operand) {
operands_[index].set(operand, this, index);
operands_[index].set(operand, this);
operand->addUse(&operands_[index]);
}
MUse *getUseFor(size_t index) {
return &operands_[index];
}
const MUse *getUseFor(size_t index) const {
return &operands_[index];
}
public:
INSTRUCTION_HEADER(AsmJSCall);
@ -10220,6 +10282,11 @@ class MAsmJSCall MOZ_FINAL : public MInstruction
size_t numOperands() const {
return operands_.length();
}
size_t indexOf(const MUse *u) const MOZ_FINAL MOZ_OVERRIDE {
MOZ_ASSERT(u >= &operands_[0]);
MOZ_ASSERT(u <= &operands_[numOperands() - 1]);
return u - &operands_[0];
}
MDefinition *getOperand(size_t index) const {
JS_ASSERT(index < numOperands());
return operands_[index].producer();

View File

@ -98,8 +98,10 @@ IsDominatedUse(MBasicBlock *block, MUse *use)
MNode *n = use->consumer();
bool isPhi = n->isDefinition() && n->toDefinition()->isPhi();
if (isPhi)
return block->dominates(n->block()->getPredecessor(use->index()));
if (isPhi) {
MPhi *phi = n->toDefinition()->toPhi();
return block->dominates(phi->block()->getPredecessor(phi->indexOf(use)));
}
return block->dominates(n->block());
}
@ -2426,7 +2428,7 @@ ComputeRequestedTruncateKind(MInstruction *candidate)
}
MDefinition *consumer = use->consumer()->toDefinition();
MDefinition::TruncateKind consumerKind = consumer->operandTruncateKind(use->index());
MDefinition::TruncateKind consumerKind = consumer->operandTruncateKind(consumer->indexOf(*use));
kind = Min(kind, consumerKind);
if (kind == MDefinition::NoTruncate)
break;