[llvm] r266084 - [ScheduleDAGInstrs] Handle instructions with multiple MMOs

Geoff Berry via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 12 08:50:31 PDT 2016


Author: gberry
Date: Tue Apr 12 10:50:19 2016
New Revision: 266084

URL: http://llvm.org/viewvc/llvm-project?rev=266084&view=rev
Log:
[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

Added:
    llvm/trunk/test/CodeGen/AArch64/arm64-misched-multimmo.ll
Modified:
    llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp

Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=266084&r1=266083&r2=266084&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original)
+++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Tue Apr 12 10:50:19 2016
@@ -159,45 +159,48 @@ static void getUnderlyingObjectsForInstr
                                          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;
-
-    // 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;
-  }
 
-  const Value *V = (*MI->memoperands_begin())->getValue();
-  if (!V)
-    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;
+      }
 
-  SmallVector<Value *, 4> Objs;
-  getUnderlyingObjects(V, Objs, DL);
+      // 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 (Value *V : Objs) {
-    if (!isIdentifiedObject(V)) {
+      bool MayAlias = PSV->mayAlias(MFI);
+      Objects.push_back(UnderlyingObjectsVector::value_type(PSV, MayAlias));
+    } else if (const Value *V = MMO->getValue()) {
+      SmallVector<Value *, 4> Objs;
+      getUnderlyingObjects(V, Objs, DL);
+
+      for (Value *V : Objs) {
+        if (!isIdentifiedObject(V)) {
+          Objects.clear();
+          return;
+        }
+
+        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(
           // 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);

Added: llvm/trunk/test/CodeGen/AArch64/arm64-misched-multimmo.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-misched-multimmo.ll?rev=266084&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/arm64-misched-multimmo.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/arm64-misched-multimmo.ll Tue Apr 12 10:50:19 2016
@@ -0,0 +1,23 @@
+; REQUIRES: asserts
+; RUN: llc < %s -mtriple=arm64-linux-gnu -mcpu=cortex-a57 -enable-misched=0 -debug-only=misched -o - 2>&1 > /dev/null | FileCheck %s
+
+
+ at G1 = common global [100 x i32] zeroinitializer, align 4
+ at G2 = common global [100 x i32] zeroinitializer, align 4
+
+; Check that no scheduling dependencies are created between the paired loads and the store during post-RA MI scheduling.
+;
+; CHECK-LABEL: # Machine code for function foo: Properties: <Post SSA
+; CHECK: SU(2):   %W{{[0-9]+}}<def>, %W{{[0-9]+}}<def> = LDPWi
+; CHECK: Successors:
+; CHECK-NOT: ch SU(4)
+; CHECK: SU(3)
+; CHECK: SU(4):   STRWui %WZR, %X{{[0-9]+}}
+define i32 @foo() {
+entry:
+  %0 = load i32, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @G2, i64 0, i64 0), align 4
+  %1 = load i32, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @G2, i64 0, i64 1), align 4
+  store i32 0, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @G1, i64 0, i64 0), align 4
+  %add = add nsw i32 %1, %0
+  ret i32 %add
+}




More information about the llvm-commits mailing list