mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-06 17:16:12 +00:00
Bug 1010586 - IonMonkey: Shrink the MUse class by making the index field unnecessary. r=nbp
This commit is contained in:
parent
9f78dc2ea0
commit
439e296431
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
121
js/src/jit/MIR.h
121
js/src/jit/MIR.h
@ -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();
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user