[SLPVectorizer] Remove RawInstructionsData/getMainOpcode and merge into getSameOpcode
authorSimon Pilgrim <llvm-dev@redking.me.uk>
Thu, 14 Jun 2018 10:25:19 +0000 (10:25 +0000)
committerSimon Pilgrim <llvm-dev@redking.me.uk>
Thu, 14 Jun 2018 10:25:19 +0000 (10:25 +0000)
This is part of the work to cleanup use of 'alternate' ops so we can use the more general SK_Select shuffle type.

Only getSameOpcode calls getMainOpcode and much of the logic is repeated in both functions. This will require some reworking of D28907 but that patch has hit trouble and is unlikely to be completed anytime soon.

Differential Revision: https://reviews.llvm.org/D48120

llvm-svn: 334701

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

index 04b6a76c9d400e709360615baafb828a5ff35223..bf2667e34b9921f68e87f97fe7db2de45ed5b597 100644 (file)
@@ -363,40 +363,6 @@ static Value *isOneOf(Value *OpValue, Value *Op) {
 
 namespace {
 
-/// Contains data for the instructions going to be vectorized.
-struct RawInstructionsData {
-  /// Main Opcode of the instructions going to be vectorized.
-  unsigned Opcode = 0;
-
-  /// The list of instructions have some instructions with alternate opcodes.
-  bool HasAltOpcodes = false;
-};
-
-} // end anonymous namespace
-
-/// Checks the list of the vectorized instructions \p VL and returns info about
-/// this list.
-static RawInstructionsData getMainOpcode(ArrayRef<Value *> VL) {
-  auto *I0 = dyn_cast<Instruction>(VL[0]);
-  if (!I0)
-    return {};
-  RawInstructionsData Res;
-  unsigned Opcode = I0->getOpcode();
-  // Walk through the list of the vectorized instructions
-  // in order to check its structure described by RawInstructionsData.
-  for (unsigned Cnt = 0, E = VL.size(); Cnt != E; ++Cnt) {
-    auto *I = dyn_cast<Instruction>(VL[Cnt]);
-    if (!I)
-      return {};
-    if (Opcode != I->getOpcode())
-      Res.HasAltOpcodes = true;
-  }
-  Res.Opcode = Opcode;
-  return Res;
-}
-
-namespace {
-
 /// Main data required for vectorization of instructions.
 struct InstructionsState {
   /// The very first instruction in the list with the main opcode.
@@ -419,21 +385,26 @@ struct InstructionsState {
 /// InstructionsState, the Opcode that we suppose the whole list 
 /// could be vectorized even if its structure is diverse.
 static InstructionsState getSameOpcode(ArrayRef<Value *> VL) {
-  auto Res = getMainOpcode(VL);
-  unsigned Opcode = Res.Opcode;
-  if (!Res.HasAltOpcodes)
-    return InstructionsState(VL[0], Opcode, false);
-  unsigned AltOpcode = getAltOpcode(Opcode);
-  // Examine each element in the list instructions VL to determine
-  // if some operations there could be considered as an alternative
-  // (for example as subtraction relates to addition operation).
-  for (int Cnt = 0, E = VL.size(); Cnt < E; Cnt++) {
-    auto *I = cast<Instruction>(VL[Cnt]);
-    unsigned InstOpcode = I->getOpcode();
-    if (InstOpcode != (isOdd(Cnt) ? AltOpcode : Opcode))
-      return InstructionsState(VL[0], 0, false);
-  }
-  return InstructionsState(VL[0], Opcode, Res.HasAltOpcodes);
+  // Make sure these are all Instructions.
+  if (llvm::any_of(VL, [](Value *V) { return !isa<Instruction>(V); }))
+    return InstructionsState(VL[0], 0, false);
+
+  unsigned Opcode = cast<Instruction>(VL[0])->getOpcode();
+  bool HasAltOpcodes = llvm::any_of(VL, [Opcode](Value *V) {
+    return Opcode != cast<Instruction>(V)->getOpcode();
+  });
+
+  // Check for an alternate opcode pattern.
+  if (HasAltOpcodes) {
+    unsigned AltOpcode = getAltOpcode(Opcode);
+    for (int Cnt = 0, E = VL.size(); Cnt < E; Cnt++) {
+      unsigned InstOpcode = cast<Instruction>(VL[Cnt])->getOpcode();
+      if (InstOpcode != (isOdd(Cnt) ? AltOpcode : Opcode))
+        return InstructionsState(VL[0], 0, false);
+    }
+  }
+
+  return InstructionsState(VL[0], Opcode, HasAltOpcodes);
 }
 
 /// \returns true if all of the values in \p VL have the same type or false