Bug 1077720 - IonMonkey: AliasAnalysis: Use MInstruction to track dependencies instead of MDefinition r=nbp

This commit is contained in:
Dan Gohman 2014-10-08 15:04:13 -07:00
parent f044bd49a6
commit ea4554095f
6 changed files with 32 additions and 24 deletions

View File

@ -27,7 +27,7 @@ class LoopAliasInfo : public TempObject
private:
LoopAliasInfo *outer_;
MBasicBlock *loopHeader_;
MDefinitionVector invariantLoads_;
MInstructionVector invariantLoads_;
public:
LoopAliasInfo(TempAllocator &alloc, LoopAliasInfo *outer, MBasicBlock *loopHeader)
@ -40,13 +40,13 @@ class LoopAliasInfo : public TempObject
LoopAliasInfo *outer() const {
return outer_;
}
bool addInvariantLoad(MDefinition *ins) {
bool addInvariantLoad(MInstruction *ins) {
return invariantLoads_.append(ins);
}
const MDefinitionVector& invariantLoads() const {
const MInstructionVector& invariantLoads() const {
return invariantLoads_;
}
MDefinition *firstInstruction() const {
MInstruction *firstInstruction() const {
return *loopHeader_->begin();
}
};
@ -123,7 +123,7 @@ BlockMightReach(MBasicBlock *src, MBasicBlock *dest)
}
static void
IonSpewDependency(MDefinition *load, MDefinition *store, const char *verb, const char *reason)
IonSpewDependency(MInstruction *load, MInstruction *store, const char *verb, const char *reason)
{
if (!JitSpewEnabled(JitSpew_Alias))
return;
@ -136,7 +136,7 @@ IonSpewDependency(MDefinition *load, MDefinition *store, const char *verb, const
}
static void
IonSpewAliasInfo(const char *pre, MDefinition *ins, const char *post)
IonSpewAliasInfo(const char *pre, MInstruction *ins, const char *post)
{
if (!JitSpewEnabled(JitSpew_Alias))
return;
@ -163,12 +163,12 @@ IonSpewAliasInfo(const char *pre, MDefinition *ins, const char *post)
bool
AliasAnalysis::analyze()
{
Vector<MDefinitionVector, AliasSet::NumCategories, IonAllocPolicy> stores(alloc());
Vector<MInstructionVector, AliasSet::NumCategories, IonAllocPolicy> stores(alloc());
// Initialize to the first instruction.
MDefinition *firstIns = *graph_.entryBlock()->begin();
MInstruction *firstIns = *graph_.entryBlock()->begin();
for (unsigned i = 0; i < AliasSet::NumCategories; i++) {
MDefinitionVector defs(alloc());
MInstructionVector defs(alloc());
if (!defs.append(firstIns))
return false;
if (!stores.append(Move(defs)))
@ -188,7 +188,13 @@ AliasAnalysis::analyze()
loop_ = new(alloc()) LoopAliasInfo(alloc(), loop_, *block);
}
for (MDefinitionIterator def(*block); def; def++) {
for (MPhiIterator def(block->phisBegin()), end(block->phisEnd()); def != end; ++def)
def->setId(newId++);
for (MInstructionIterator def(block->begin()), end(block->begin(block->lastIns()));
def != end;
++def)
{
def->setId(newId++);
AliasSet set = def->getAliasSet();
@ -208,12 +214,12 @@ AliasAnalysis::analyze()
}
} else {
// Find the most recent store on which this instruction depends.
MDefinition *lastStore = firstIns;
MInstruction *lastStore = firstIns;
for (AliasSetIterator iter(set); iter; iter++) {
MDefinitionVector &aliasedStores = stores[*iter];
MInstructionVector &aliasedStores = stores[*iter];
for (int i = aliasedStores.length() - 1; i >= 0; i--) {
MDefinition *store = aliasedStores[i];
MInstruction *store = aliasedStores[i];
if (def->mightAlias(store) && BlockMightReach(store->block(), *block)) {
if (lastStore->id() < store->id())
lastStore = store;
@ -245,18 +251,18 @@ AliasAnalysis::analyze()
LoopAliasInfo *outerLoop = loop_->outer();
MInstruction *firstLoopIns = *loop_->loopHeader()->begin();
const MDefinitionVector &invariant = loop_->invariantLoads();
const MInstructionVector &invariant = loop_->invariantLoads();
for (unsigned i = 0; i < invariant.length(); i++) {
MDefinition *ins = invariant[i];
MInstruction *ins = invariant[i];
AliasSet set = ins->getAliasSet();
MOZ_ASSERT(set.isLoad());
bool hasAlias = false;
for (AliasSetIterator iter(set); iter; iter++) {
MDefinitionVector &aliasedStores = stores[*iter];
MInstructionVector &aliasedStores = stores[*iter];
for (int i = aliasedStores.length() - 1;; i--) {
MDefinition *store = aliasedStores[i];
MInstruction *store = aliasedStores[i];
if (store->id() < firstLoopIns->id())
break;
if (ins->mightAlias(store)) {

View File

@ -1844,6 +1844,7 @@ jit::AssertBasicGraphCoherency(MIRGraph &graph)
MOZ_ASSERT(phi->numOperands() == block->numPredecessors());
MOZ_ASSERT(!phi->isRecoveredOnBailout());
MOZ_ASSERT(phi->type() != MIRType_None);
MOZ_ASSERT(phi->dependency() == nullptr);
}
for (MDefinitionIterator iter(*block); iter; iter++) {
MOZ_ASSERT(iter->block() == *block);

View File

@ -123,7 +123,7 @@ static bool
HasDependencyInLoop(MInstruction *ins, MBasicBlock *header)
{
// Don't hoist if this instruction depends on a store inside the loop.
if (MDefinition *dep = ins->dependency())
if (MInstruction *dep = ins->dependency())
return !IsBeforeLoop(dep, header);
return false;
}

View File

@ -189,7 +189,7 @@ MDefinition::valueHash() const
HashNumber out = op();
for (size_t i = 0, e = numOperands(); i < e; i++)
out = addU32ToHash(out, getOperand(i)->id());
if (MDefinition *dep = dependency())
if (MInstruction *dep = dependency())
out = addU32ToHash(out, dep->id());
return out;
}

View File

@ -347,9 +347,9 @@ class MDefinition : public MNode
MIRType resultType_; // Representation of result type.
types::TemporaryTypeSet *resultTypeSet_; // Optional refinement of the result type.
union {
MDefinition *dependency_; // Implicit dependency (store, call, etc.) of this instruction.
MInstruction *dependency_; // Implicit dependency (store, call, etc.) of this instruction.
// Used by alias analysis, GVN and LICM.
uint32_t virtualRegister_; // Used by lowering to map definitions to virtual registers.
uint32_t virtualRegister_; // Used by lowering to map definitions to virtual registers.
};
// Track bailouts by storing the current pc in MIR instruction. Also used
@ -746,10 +746,10 @@ class MDefinition : public MNode
resultTypeSet_ = types;
}
MDefinition *dependency() const {
MInstruction *dependency() const {
return dependency_;
}
void setDependency(MDefinition *dependency) {
void setDependency(MInstruction *dependency) {
dependency_ = dependency;
}
virtual AliasSet getAliasSet() const {
@ -825,6 +825,7 @@ class MUseDefIterator
};
typedef Vector<MDefinition *, 8, IonAllocPolicy> MDefinitionVector;
typedef Vector<MInstruction *, 6, IonAllocPolicy> MInstructionVector;
// An instruction is an SSA name that is inserted into a basic block's IR
// stream.

View File

@ -703,7 +703,7 @@ ValueNumberer::visitDefinition(MDefinition *def)
{
// If this instruction has a dependency() into an unreachable block, we'll
// need to update AliasAnalysis.
MDefinition *dep = def->dependency();
MInstruction *dep = def->dependency();
if (dep != nullptr && (dep->isDiscarded() || dep->block()->isDead())) {
JitSpew(JitSpew_GVN, " AliasAnalysis invalidated");
if (updateAliasAnalysis_ && !dependenciesBroken_) {