diff options
author | Geoff Berry <gberry@codeaurora.org> | 2016-04-12 15:50:19 +0000 |
---|---|---|
committer | Geoff Berry <gberry@codeaurora.org> | 2016-04-12 15:50:19 +0000 |
commit | c0739d83056ba36cd3941475bacc0f6d6dc6b2b8 (patch) | |
tree | d3487f93ae4b0e7b210c1705c4256eb6aa359145 /llvm/lib/CodeGen | |
parent | c5cec39c0ee0f13cc9ab15a828b746e3cbb2fc03 (diff) | |
download | bcm5719-llvm-c0739d83056ba36cd3941475bacc0f6d6dc6b2b8.tar.gz bcm5719-llvm-c0739d83056ba36cd3941475bacc0f6d6dc6b2b8.zip |
[ScheduleDAGInstrs] Handle instructions with multiple MMOs
Summary:
In getUnderlyingObjectsForInstr(): Don't give up on instructions with
multiple MMOs, instead look through all the MMOs and if they all meet
the conservative criteria previously used for single MMO instructions,
then return all of the underlying objects derived from the MMOs.
The change to ScheduleDAGInstrs::buildSchedGraph() is needed to avoid
the case where multiple underlying objects are present and are related
in such a way that successive iterations of the loop end up adding a
dependency from an instruction to itself.
Reviewers: atrick, hfinkel
Subscribers: MatzeB, mcrosier, llvm-commits
Differential Revision: http://reviews.llvm.org/D18093
llvm-svn: 266084
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/ScheduleDAGInstrs.cpp | 71 |
1 files changed, 41 insertions, 30 deletions
diff --git a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp index 61b636d6868..c9c9a47a795 100644 --- a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -159,45 +159,48 @@ static void getUnderlyingObjectsForInstr(const MachineInstr *MI, const MachineFrameInfo *MFI, UnderlyingObjectsVector &Objects, const DataLayout &DL) { - if (!MI->hasOneMemOperand() || - (!(*MI->memoperands_begin())->getValue() && - !(*MI->memoperands_begin())->getPseudoValue()) || - (*MI->memoperands_begin())->isVolatile()) - return; - - if (const PseudoSourceValue *PSV = - (*MI->memoperands_begin())->getPseudoValue()) { - // Function that contain tail calls don't have unique PseudoSourceValue - // objects. Two PseudoSourceValues might refer to the same or overlapping - // locations. The client code calling this function assumes this is not the - // case. So return a conservative answer of no known object. - if (MFI->hasTailCall()) + for (auto *MMO : MI->memoperands()) { + if (MMO->isVolatile()) { + Objects.clear(); return; + } + + if (const PseudoSourceValue *PSV = MMO->getPseudoValue()) { + // Function that contain tail calls don't have unique PseudoSourceValue + // objects. Two PseudoSourceValues might refer to the same or overlapping + // locations. The client code calling this function assumes this is not the + // case. So return a conservative answer of no known object. + if (MFI->hasTailCall()) { + Objects.clear(); + return; + } + + // For now, ignore PseudoSourceValues which may alias LLVM IR values + // because the code that uses this function has no way to cope with + // such aliases. + if (PSV->isAliased(MFI)) { + Objects.clear(); + return; + } - // For now, ignore PseudoSourceValues which may alias LLVM IR values - // because the code that uses this function has no way to cope with - // such aliases. - if (!PSV->isAliased(MFI)) { bool MayAlias = PSV->mayAlias(MFI); Objects.push_back(UnderlyingObjectsVector::value_type(PSV, MayAlias)); - } - return; - } + } else if (const Value *V = MMO->getValue()) { + SmallVector<Value *, 4> Objs; + getUnderlyingObjects(V, Objs, DL); - const Value *V = (*MI->memoperands_begin())->getValue(); - if (!V) - return; - - SmallVector<Value *, 4> Objs; - getUnderlyingObjects(V, Objs, DL); + for (Value *V : Objs) { + if (!isIdentifiedObject(V)) { + Objects.clear(); + return; + } - for (Value *V : Objs) { - if (!isIdentifiedObject(V)) { + Objects.push_back(UnderlyingObjectsVector::value_type(V, true)); + } + } else { Objects.clear(); return; } - - Objects.push_back(UnderlyingObjectsVector::value_type(V, true)); } } @@ -1037,6 +1040,14 @@ void ScheduleDAGInstrs::buildSchedGraph(AliasAnalysis *AA, // Add dependencies to previous stores and loads mapped to V. addChainDependencies(SU, stores_, V); addChainDependencies(SU, (ThisMayAlias ? Loads : NonAliasLoads), V); + } + // Update the store map after all chains have been added to avoid adding + // self-loop edge if multiple underlying objects are present. + for (auto &underlObj : Objs) { + ValueType V = underlObj.getPointer(); + bool ThisMayAlias = underlObj.getInt(); + + Value2SUsMap &stores_ = (ThisMayAlias ? Stores : NonAliasStores); // Map this store to V. stores_.insert(SU, V); |