[llvm] a7fbca4 - [NFC] Extract `CodeGenInstAlias` into its own *.h/*.cpp

Sergei Barannikov via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 31 18:24:01 PST 2023


Author: Sergei Barannikov
Date: 2023-02-01T05:23:43+03:00
New Revision: a7fbca40805ca414a9dc37b91075e89e6a3b75d5

URL: https://github.com/llvm/llvm-project/commit/a7fbca40805ca414a9dc37b91075e89e6a3b75d5
DIFF: https://github.com/llvm/llvm-project/commit/a7fbca40805ca414a9dc37b91075e89e6a3b75d5.diff

LOG: [NFC] Extract `CodeGenInstAlias` into its own *.h/*.cpp

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

Added: 
    llvm/utils/TableGen/CodeGenInstAlias.cpp
    llvm/utils/TableGen/CodeGenInstAlias.h

Modified: 
    clang/docs/tools/clang-formatted-files.txt
    llvm/utils/TableGen/AsmMatcherEmitter.cpp
    llvm/utils/TableGen/AsmWriterEmitter.cpp
    llvm/utils/TableGen/CMakeLists.txt
    llvm/utils/TableGen/CodeGenInstruction.cpp
    llvm/utils/TableGen/CodeGenInstruction.h
    llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn

Removed: 
    


################################################################################
diff  --git a/clang/docs/tools/clang-formatted-files.txt b/clang/docs/tools/clang-formatted-files.txt
index cbac961982e6a..aa9b871ea58cb 100644
--- a/clang/docs/tools/clang-formatted-files.txt
+++ b/clang/docs/tools/clang-formatted-files.txt
@@ -7418,6 +7418,8 @@ llvm/unittests/XRay/FDRRecordsTest.cpp
 llvm/unittests/XRay/FDRTraceWriterTest.cpp
 llvm/unittests/XRay/ProfileTest.cpp
 llvm/utils/not/not.cpp
+llvm/Utils/TableGen/CodeGenInstAlias.cpp
+llvm/Utils/TableGen/CodeGenInstAlias.h
 llvm/utils/TableGen/CodeBeadsGen.cpp
 llvm/utils/TableGen/CompressInstEmitter.cpp
 llvm/utils/TableGen/DFAEmitter.h

diff  --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index c13e5b5deff6f..4b37347bbae62 100644
--- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -95,6 +95,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "CodeGenInstAlias.h"
 #include "CodeGenInstruction.h"
 #include "CodeGenTarget.h"
 #include "SubtargetFeatureInfo.h"

diff  --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index f2e4d15a2c755..e7c0604b8ec75 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "AsmWriterInst.h"
+#include "CodeGenInstAlias.h"
 #include "CodeGenInstruction.h"
 #include "CodeGenRegisters.h"
 #include "CodeGenTarget.h"

diff  --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt
index aa16e7e894aca..44ed5549c8ea3 100644
--- a/llvm/utils/TableGen/CMakeLists.txt
+++ b/llvm/utils/TableGen/CMakeLists.txt
@@ -13,6 +13,7 @@ add_tablegen(llvm-tblgen LLVM
   CodeEmitterGen.cpp
   CodeGenDAGPatterns.cpp
   CodeGenHwModes.cpp
+  CodeGenInstAlias.cpp
   CodeGenInstruction.cpp
   CodeGenMapTable.cpp
   CodeGenRegisters.cpp

diff  --git a/llvm/utils/TableGen/CodeGenInstAlias.cpp b/llvm/utils/TableGen/CodeGenInstAlias.cpp
new file mode 100644
index 0000000000000..f3e722d17866a
--- /dev/null
+++ b/llvm/utils/TableGen/CodeGenInstAlias.cpp
@@ -0,0 +1,282 @@
+//===- CodeGenInstAlias.cpp - CodeGen InstAlias Class Wrapper -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the CodeGenInstAlias class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenInstAlias.h"
+#include "CodeGenInstruction.h"
+#include "CodeGenTarget.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+
+using namespace llvm;
+
+/// tryAliasOpMatch - This is a helper function for the CodeGenInstAlias
+/// constructor.  It checks if an argument in an InstAlias pattern matches
+/// the corresponding operand of the instruction.  It returns true on a
+/// successful match, with ResOp set to the result operand to be used.
+bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
+                                       Record *InstOpRec, bool hasSubOps,
+                                       ArrayRef<SMLoc> Loc, CodeGenTarget &T,
+                                       ResultOperand &ResOp) {
+  Init *Arg = Result->getArg(AliasOpNo);
+  DefInit *ADI = dyn_cast<DefInit>(Arg);
+  Record *ResultRecord = ADI ? ADI->getDef() : nullptr;
+
+  if (ADI && ADI->getDef() == InstOpRec) {
+    // If the operand is a record, it must have a name, and the record type
+    // must match up with the instruction's argument type.
+    if (!Result->getArgName(AliasOpNo))
+      PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
+                               " must have a name!");
+    ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
+                          ResultRecord);
+    return true;
+  }
+
+  // For register operands, the source register class can be a subclass
+  // of the instruction register class, not just an exact match.
+  if (InstOpRec->isSubClassOf("RegisterOperand"))
+    InstOpRec = InstOpRec->getValueAsDef("RegClass");
+
+  if (ADI && ADI->getDef()->isSubClassOf("RegisterOperand"))
+    ADI = ADI->getDef()->getValueAsDef("RegClass")->getDefInit();
+
+  if (ADI && ADI->getDef()->isSubClassOf("RegisterClass")) {
+    if (!InstOpRec->isSubClassOf("RegisterClass"))
+      return false;
+    if (!T.getRegisterClass(InstOpRec).hasSubClass(
+            &T.getRegisterClass(ADI->getDef())))
+      return false;
+    ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
+                          ResultRecord);
+    return true;
+  }
+
+  // Handle explicit registers.
+  if (ADI && ADI->getDef()->isSubClassOf("Register")) {
+    if (InstOpRec->isSubClassOf("OptionalDefOperand")) {
+      DagInit *DI = InstOpRec->getValueAsDag("MIOperandInfo");
+      // The operand info should only have a single (register) entry. We
+      // want the register class of it.
+      InstOpRec = cast<DefInit>(DI->getArg(0))->getDef();
+    }
+
+    if (!InstOpRec->isSubClassOf("RegisterClass"))
+      return false;
+
+    if (!T.getRegisterClass(InstOpRec).contains(
+            T.getRegBank().getReg(ADI->getDef())))
+      PrintFatalError(Loc, "fixed register " + ADI->getDef()->getName() +
+                               " is not a member of the " +
+                               InstOpRec->getName() + " register class!");
+
+    if (Result->getArgName(AliasOpNo))
+      PrintFatalError(Loc, "result fixed register argument must "
+                           "not have a name!");
+
+    ResOp = ResultOperand(ResultRecord);
+    return true;
+  }
+
+  // Handle "zero_reg" for optional def operands.
+  if (ADI && ADI->getDef()->getName() == "zero_reg") {
+
+    // Check if this is an optional def.
+    // Tied operands where the source is a sub-operand of a complex operand
+    // need to represent both operands in the alias destination instruction.
+    // Allow zero_reg for the tied portion. This can and should go away once
+    // the MC representation of things doesn't use tied operands at all.
+    // if (!InstOpRec->isSubClassOf("OptionalDefOperand"))
+    //  throw TGError(Loc, "reg0 used for result that is not an "
+    //                "OptionalDefOperand!");
+
+    ResOp = ResultOperand(static_cast<Record *>(nullptr));
+    return true;
+  }
+
+  // Literal integers.
+  if (IntInit *II = dyn_cast<IntInit>(Arg)) {
+    if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
+      return false;
+    // Integer arguments can't have names.
+    if (Result->getArgName(AliasOpNo))
+      PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
+                               " must not have a name!");
+    ResOp = ResultOperand(II->getValue());
+    return true;
+  }
+
+  // Bits<n> (also used for 0bxx literals)
+  if (BitsInit *BI = dyn_cast<BitsInit>(Arg)) {
+    if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
+      return false;
+    if (!BI->isComplete())
+      return false;
+    // Convert the bits init to an integer and use that for the result.
+    IntInit *II = dyn_cast_or_null<IntInit>(
+        BI->convertInitializerTo(IntRecTy::get(BI->getRecordKeeper())));
+    if (!II)
+      return false;
+    ResOp = ResultOperand(II->getValue());
+    return true;
+  }
+
+  // If both are Operands with the same MVT, allow the conversion. It's
+  // up to the user to make sure the values are appropriate, just like
+  // for isel Pat's.
+  if (InstOpRec->isSubClassOf("Operand") && ADI &&
+      ADI->getDef()->isSubClassOf("Operand")) {
+    // FIXME: What other attributes should we check here? Identical
+    // MIOperandInfo perhaps?
+    if (InstOpRec->getValueInit("Type") != ADI->getDef()->getValueInit("Type"))
+      return false;
+    ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
+                          ADI->getDef());
+    return true;
+  }
+
+  return false;
+}
+
+unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const {
+  if (!isRecord())
+    return 1;
+
+  Record *Rec = getRecord();
+  if (!Rec->isSubClassOf("Operand"))
+    return 1;
+
+  DagInit *MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
+  if (MIOpInfo->getNumArgs() == 0) {
+    // Unspecified, so it defaults to 1
+    return 1;
+  }
+
+  return MIOpInfo->getNumArgs();
+}
+
+CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) {
+  Result = R->getValueAsDag("ResultInst");
+  AsmString = std::string(R->getValueAsString("AsmString"));
+
+  // Verify that the root of the result is an instruction.
+  DefInit *DI = dyn_cast<DefInit>(Result->getOperator());
+  if (!DI || !DI->getDef()->isSubClassOf("Instruction"))
+    PrintFatalError(R->getLoc(),
+                    "result of inst alias should be an instruction");
+
+  ResultInst = &T.getInstruction(DI->getDef());
+
+  // NameClass - If argument names are repeated, we need to verify they have
+  // the same class.
+  StringMap<Record *> NameClass;
+  for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
+    DefInit *ADI = dyn_cast<DefInit>(Result->getArg(i));
+    if (!ADI || !Result->getArgName(i))
+      continue;
+    // Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
+    // $foo can exist multiple times in the result list, but it must have the
+    // same type.
+    Record *&Entry = NameClass[Result->getArgNameStr(i)];
+    if (Entry && Entry != ADI->getDef())
+      PrintFatalError(R->getLoc(), "result value $" + Result->getArgNameStr(i) +
+                                       " is both " + Entry->getName() +
+                                       " and " + ADI->getDef()->getName() +
+                                       "!");
+    Entry = ADI->getDef();
+  }
+
+  // Decode and validate the arguments of the result.
+  unsigned AliasOpNo = 0;
+  for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
+
+    // Tied registers don't have an entry in the result dag unless they're part
+    // of a complex operand, in which case we include them anyways, as we
+    // don't have any other way to specify the whole operand.
+    if (ResultInst->Operands[i].MINumOperands == 1 &&
+        ResultInst->Operands[i].getTiedRegister() != -1) {
+      // Tied operands of 
diff erent RegisterClass should be explicit within an
+      // instruction's syntax and so cannot be skipped.
+      int TiedOpNum = ResultInst->Operands[i].getTiedRegister();
+      if (ResultInst->Operands[i].Rec->getName() ==
+          ResultInst->Operands[TiedOpNum].Rec->getName())
+        continue;
+    }
+
+    if (AliasOpNo >= Result->getNumArgs())
+      PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
+
+    Record *InstOpRec = ResultInst->Operands[i].Rec;
+    unsigned NumSubOps = ResultInst->Operands[i].MINumOperands;
+    ResultOperand ResOp(static_cast<int64_t>(0));
+    if (tryAliasOpMatch(Result, AliasOpNo, InstOpRec, (NumSubOps > 1),
+                        R->getLoc(), T, ResOp)) {
+      // If this is a simple operand, or a complex operand with a custom match
+      // class, then we can match is verbatim.
+      if (NumSubOps == 1 || (InstOpRec->getValue("ParserMatchClass") &&
+                             InstOpRec->getValueAsDef("ParserMatchClass")
+                                     ->getValueAsString("Name") != "Imm")) {
+        ResultOperands.push_back(ResOp);
+        ResultInstOperandIndex.push_back(std::make_pair(i, -1));
+        ++AliasOpNo;
+
+        // Otherwise, we need to match each of the suboperands individually.
+      } else {
+        DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
+        for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
+          Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();
+
+          // Take care to instantiate each of the suboperands with the correct
+          // nomenclature: $foo.bar
+          ResultOperands.emplace_back(
+              Result->getArgName(AliasOpNo)->getAsUnquotedString() + "." +
+                  MIOI->getArgName(SubOp)->getAsUnquotedString(),
+              SubRec);
+          ResultInstOperandIndex.push_back(std::make_pair(i, SubOp));
+        }
+        ++AliasOpNo;
+      }
+      continue;
+    }
+
+    // If the argument did not match the instruction operand, and the operand
+    // is composed of multiple suboperands, try matching the suboperands.
+    if (NumSubOps > 1) {
+      DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
+      for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
+        if (AliasOpNo >= Result->getNumArgs())
+          PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
+        Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();
+        if (tryAliasOpMatch(Result, AliasOpNo, SubRec, false, R->getLoc(), T,
+                            ResOp)) {
+          ResultOperands.push_back(ResOp);
+          ResultInstOperandIndex.push_back(std::make_pair(i, SubOp));
+          ++AliasOpNo;
+        } else {
+          PrintFatalError(
+              R->getLoc(),
+              "result argument #" + Twine(AliasOpNo) +
+                  " does not match instruction operand class " +
+                  (SubOp == 0 ? InstOpRec->getName() : SubRec->getName()));
+        }
+      }
+      continue;
+    }
+    PrintFatalError(R->getLoc(),
+                    "result argument #" + Twine(AliasOpNo) +
+                        " does not match instruction operand class " +
+                        InstOpRec->getName());
+  }
+
+  if (AliasOpNo != Result->getNumArgs())
+    PrintFatalError(R->getLoc(), "too many operands for instruction!");
+}

diff  --git a/llvm/utils/TableGen/CodeGenInstAlias.h b/llvm/utils/TableGen/CodeGenInstAlias.h
new file mode 100644
index 0000000000000..2a05273e72701
--- /dev/null
+++ b/llvm/utils/TableGen/CodeGenInstAlias.h
@@ -0,0 +1,105 @@
+//===- CodeGenInstAlias.h - InstAlias Class Wrapper -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a wrapper class for the 'InstAlias' TableGen class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_UTILS_TABLEGEN_CODEGENINSTALIAS_H
+#define LLVM_UTILS_TABLEGEN_CODEGENINSTALIAS_H
+
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <cstdint>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+template <typename T> class ArrayRef;
+class CodeGenInstruction;
+class CodeGenTarget;
+class DagInit;
+class SMLoc;
+class Record;
+
+/// CodeGenInstAlias - This represents an InstAlias definition.
+class CodeGenInstAlias {
+public:
+  Record *TheDef; // The actual record defining this InstAlias.
+
+  /// AsmString - The format string used to emit a .s file for the
+  /// instruction.
+  std::string AsmString;
+
+  /// Result - The result instruction.
+  DagInit *Result;
+
+  /// ResultInst - The instruction generated by the alias (decoded from
+  /// Result).
+  CodeGenInstruction *ResultInst;
+
+  struct ResultOperand {
+  private:
+    std::string Name;
+    Record *R = nullptr;
+    int64_t Imm = 0;
+
+  public:
+    enum { K_Record, K_Imm, K_Reg } Kind;
+
+    ResultOperand(std::string N, Record *r)
+        : Name(std::move(N)), R(r), Kind(K_Record) {}
+    ResultOperand(int64_t I) : Imm(I), Kind(K_Imm) {}
+    ResultOperand(Record *r) : R(r), Kind(K_Reg) {}
+
+    bool isRecord() const { return Kind == K_Record; }
+    bool isImm() const { return Kind == K_Imm; }
+    bool isReg() const { return Kind == K_Reg; }
+
+    StringRef getName() const {
+      assert(isRecord());
+      return Name;
+    }
+    Record *getRecord() const {
+      assert(isRecord());
+      return R;
+    }
+    int64_t getImm() const {
+      assert(isImm());
+      return Imm;
+    }
+    Record *getRegister() const {
+      assert(isReg());
+      return R;
+    }
+
+    unsigned getMINumOperands() const;
+  };
+
+  /// ResultOperands - The decoded operands for the result instruction.
+  std::vector<ResultOperand> ResultOperands;
+
+  /// ResultInstOperandIndex - For each operand, this vector holds a pair of
+  /// indices to identify the corresponding operand in the result
+  /// instruction.  The first index specifies the operand and the second
+  /// index specifies the suboperand.  If there are no suboperands or if all
+  /// of them are matched by the operand, the second value should be -1.
+  std::vector<std::pair<unsigned, int>> ResultInstOperandIndex;
+
+  CodeGenInstAlias(Record *R, CodeGenTarget &T);
+
+  bool tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, Record *InstOpRec,
+                       bool hasSubOps, ArrayRef<SMLoc> Loc, CodeGenTarget &T,
+                       ResultOperand &ResOp);
+};
+
+} // namespace llvm
+
+#endif // LLVM_UTILS_TABLEGEN_CODEGENINSTALIAS_H

diff  --git a/llvm/utils/TableGen/CodeGenInstruction.cpp b/llvm/utils/TableGen/CodeGenInstruction.cpp
index 238c6a1b6ba8c..11133918a8ff2 100644
--- a/llvm/utils/TableGen/CodeGenInstruction.cpp
+++ b/llvm/utils/TableGen/CodeGenInstruction.cpp
@@ -13,7 +13,6 @@
 #include "CodeGenInstruction.h"
 #include "CodeGenTarget.h"
 #include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringMap.h"
 #include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/Record.h"
 #include <set>
@@ -592,266 +591,3 @@ bool CodeGenInstruction::isOperandImpl(StringRef OpListName, unsigned i,
   return Constraint->getDef()->isSubClassOf("TypedOperand") &&
          Constraint->getDef()->getValueAsBit(PropertyName);
 }
-
-//===----------------------------------------------------------------------===//
-/// CodeGenInstAlias Implementation
-//===----------------------------------------------------------------------===//
-
-/// tryAliasOpMatch - This is a helper function for the CodeGenInstAlias
-/// constructor.  It checks if an argument in an InstAlias pattern matches
-/// the corresponding operand of the instruction.  It returns true on a
-/// successful match, with ResOp set to the result operand to be used.
-bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
-                                       Record *InstOpRec, bool hasSubOps,
-                                       ArrayRef<SMLoc> Loc, CodeGenTarget &T,
-                                       ResultOperand &ResOp) {
-  Init *Arg = Result->getArg(AliasOpNo);
-  DefInit *ADI = dyn_cast<DefInit>(Arg);
-  Record *ResultRecord = ADI ? ADI->getDef() : nullptr;
-
-  if (ADI && ADI->getDef() == InstOpRec) {
-    // If the operand is a record, it must have a name, and the record type
-    // must match up with the instruction's argument type.
-    if (!Result->getArgName(AliasOpNo))
-      PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
-                           " must have a name!");
-    ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
-                          ResultRecord);
-    return true;
-  }
-
-  // For register operands, the source register class can be a subclass
-  // of the instruction register class, not just an exact match.
-  if (InstOpRec->isSubClassOf("RegisterOperand"))
-    InstOpRec = InstOpRec->getValueAsDef("RegClass");
-
-  if (ADI && ADI->getDef()->isSubClassOf("RegisterOperand"))
-    ADI = ADI->getDef()->getValueAsDef("RegClass")->getDefInit();
-
-  if (ADI && ADI->getDef()->isSubClassOf("RegisterClass")) {
-    if (!InstOpRec->isSubClassOf("RegisterClass"))
-      return false;
-    if (!T.getRegisterClass(InstOpRec)
-              .hasSubClass(&T.getRegisterClass(ADI->getDef())))
-      return false;
-    ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
-                          ResultRecord);
-    return true;
-  }
-
-  // Handle explicit registers.
-  if (ADI && ADI->getDef()->isSubClassOf("Register")) {
-    if (InstOpRec->isSubClassOf("OptionalDefOperand")) {
-      DagInit *DI = InstOpRec->getValueAsDag("MIOperandInfo");
-      // The operand info should only have a single (register) entry. We
-      // want the register class of it.
-      InstOpRec = cast<DefInit>(DI->getArg(0))->getDef();
-    }
-
-    if (!InstOpRec->isSubClassOf("RegisterClass"))
-      return false;
-
-    if (!T.getRegisterClass(InstOpRec)
-        .contains(T.getRegBank().getReg(ADI->getDef())))
-      PrintFatalError(Loc, "fixed register " + ADI->getDef()->getName() +
-                      " is not a member of the " + InstOpRec->getName() +
-                      " register class!");
-
-    if (Result->getArgName(AliasOpNo))
-      PrintFatalError(Loc, "result fixed register argument must "
-                      "not have a name!");
-
-    ResOp = ResultOperand(ResultRecord);
-    return true;
-  }
-
-  // Handle "zero_reg" for optional def operands.
-  if (ADI && ADI->getDef()->getName() == "zero_reg") {
-
-    // Check if this is an optional def.
-    // Tied operands where the source is a sub-operand of a complex operand
-    // need to represent both operands in the alias destination instruction.
-    // Allow zero_reg for the tied portion. This can and should go away once
-    // the MC representation of things doesn't use tied operands at all.
-    //if (!InstOpRec->isSubClassOf("OptionalDefOperand"))
-    //  throw TGError(Loc, "reg0 used for result that is not an "
-    //                "OptionalDefOperand!");
-
-    ResOp = ResultOperand(static_cast<Record*>(nullptr));
-    return true;
-  }
-
-  // Literal integers.
-  if (IntInit *II = dyn_cast<IntInit>(Arg)) {
-    if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
-      return false;
-    // Integer arguments can't have names.
-    if (Result->getArgName(AliasOpNo))
-      PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
-                      " must not have a name!");
-    ResOp = ResultOperand(II->getValue());
-    return true;
-  }
-
-  // Bits<n> (also used for 0bxx literals)
-  if (BitsInit *BI = dyn_cast<BitsInit>(Arg)) {
-    if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
-      return false;
-    if (!BI->isComplete())
-      return false;
-    // Convert the bits init to an integer and use that for the result.
-    IntInit *II = dyn_cast_or_null<IntInit>(
-        BI->convertInitializerTo(IntRecTy::get(BI->getRecordKeeper())));
-    if (!II)
-      return false;
-    ResOp = ResultOperand(II->getValue());
-    return true;
-  }
-
-  // If both are Operands with the same MVT, allow the conversion. It's
-  // up to the user to make sure the values are appropriate, just like
-  // for isel Pat's.
-  if (InstOpRec->isSubClassOf("Operand") && ADI &&
-      ADI->getDef()->isSubClassOf("Operand")) {
-    // FIXME: What other attributes should we check here? Identical
-    // MIOperandInfo perhaps?
-    if (InstOpRec->getValueInit("Type") != ADI->getDef()->getValueInit("Type"))
-      return false;
-    ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
-                          ADI->getDef());
-    return true;
-  }
-
-  return false;
-}
-
-unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const {
-  if (!isRecord())
-    return 1;
-
-  Record *Rec = getRecord();
-  if (!Rec->isSubClassOf("Operand"))
-    return 1;
-
-  DagInit *MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
-  if (MIOpInfo->getNumArgs() == 0) {
-    // Unspecified, so it defaults to 1
-    return 1;
-  }
-
-  return MIOpInfo->getNumArgs();
-}
-
-CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T)
-    : TheDef(R) {
-  Result = R->getValueAsDag("ResultInst");
-  AsmString = std::string(R->getValueAsString("AsmString"));
-
-  // Verify that the root of the result is an instruction.
-  DefInit *DI = dyn_cast<DefInit>(Result->getOperator());
-  if (!DI || !DI->getDef()->isSubClassOf("Instruction"))
-    PrintFatalError(R->getLoc(),
-                    "result of inst alias should be an instruction");
-
-  ResultInst = &T.getInstruction(DI->getDef());
-
-  // NameClass - If argument names are repeated, we need to verify they have
-  // the same class.
-  StringMap<Record*> NameClass;
-  for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
-    DefInit *ADI = dyn_cast<DefInit>(Result->getArg(i));
-    if (!ADI || !Result->getArgName(i))
-      continue;
-    // Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
-    // $foo can exist multiple times in the result list, but it must have the
-    // same type.
-    Record *&Entry = NameClass[Result->getArgNameStr(i)];
-    if (Entry && Entry != ADI->getDef())
-      PrintFatalError(R->getLoc(), "result value $" + Result->getArgNameStr(i) +
-                      " is both " + Entry->getName() + " and " +
-                      ADI->getDef()->getName() + "!");
-    Entry = ADI->getDef();
-  }
-
-  // Decode and validate the arguments of the result.
-  unsigned AliasOpNo = 0;
-  for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
-
-    // Tied registers don't have an entry in the result dag unless they're part
-    // of a complex operand, in which case we include them anyways, as we
-    // don't have any other way to specify the whole operand.
-    if (ResultInst->Operands[i].MINumOperands == 1 &&
-        ResultInst->Operands[i].getTiedRegister() != -1) {
-      // Tied operands of 
diff erent RegisterClass should be explicit within an
-      // instruction's syntax and so cannot be skipped.
-      int TiedOpNum = ResultInst->Operands[i].getTiedRegister();
-      if (ResultInst->Operands[i].Rec->getName() ==
-          ResultInst->Operands[TiedOpNum].Rec->getName())
-        continue;
-    }
-
-    if (AliasOpNo >= Result->getNumArgs())
-      PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
-
-    Record *InstOpRec = ResultInst->Operands[i].Rec;
-    unsigned NumSubOps = ResultInst->Operands[i].MINumOperands;
-    ResultOperand ResOp(static_cast<int64_t>(0));
-    if (tryAliasOpMatch(Result, AliasOpNo, InstOpRec, (NumSubOps > 1),
-                        R->getLoc(), T, ResOp)) {
-      // If this is a simple operand, or a complex operand with a custom match
-      // class, then we can match is verbatim.
-      if (NumSubOps == 1 ||
-          (InstOpRec->getValue("ParserMatchClass") &&
-           InstOpRec->getValueAsDef("ParserMatchClass")
-             ->getValueAsString("Name") != "Imm")) {
-        ResultOperands.push_back(ResOp);
-        ResultInstOperandIndex.push_back(std::make_pair(i, -1));
-        ++AliasOpNo;
-
-      // Otherwise, we need to match each of the suboperands individually.
-      } else {
-         DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
-         for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
-          Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();
-
-          // Take care to instantiate each of the suboperands with the correct
-          // nomenclature: $foo.bar
-          ResultOperands.emplace_back(
-            Result->getArgName(AliasOpNo)->getAsUnquotedString() + "." +
-            MIOI->getArgName(SubOp)->getAsUnquotedString(), SubRec);
-          ResultInstOperandIndex.push_back(std::make_pair(i, SubOp));
-         }
-         ++AliasOpNo;
-      }
-      continue;
-    }
-
-    // If the argument did not match the instruction operand, and the operand
-    // is composed of multiple suboperands, try matching the suboperands.
-    if (NumSubOps > 1) {
-      DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
-      for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
-        if (AliasOpNo >= Result->getNumArgs())
-          PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
-        Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();
-        if (tryAliasOpMatch(Result, AliasOpNo, SubRec, false,
-                            R->getLoc(), T, ResOp)) {
-          ResultOperands.push_back(ResOp);
-          ResultInstOperandIndex.push_back(std::make_pair(i, SubOp));
-          ++AliasOpNo;
-        } else {
-          PrintFatalError(R->getLoc(), "result argument #" + Twine(AliasOpNo) +
-                        " does not match instruction operand class " +
-                        (SubOp == 0 ? InstOpRec->getName() :SubRec->getName()));
-        }
-      }
-      continue;
-    }
-    PrintFatalError(R->getLoc(), "result argument #" + Twine(AliasOpNo) +
-                    " does not match instruction operand class " +
-                    InstOpRec->getName());
-  }
-
-  if (AliasOpNo != Result->getNumArgs())
-    PrintFatalError(R->getLoc(), "too many operands for instruction!");
-}

diff  --git a/llvm/utils/TableGen/CodeGenInstruction.h b/llvm/utils/TableGen/CodeGenInstruction.h
index 72626caada566..2a1f17c37834a 100644
--- a/llvm/utils/TableGen/CodeGenInstruction.h
+++ b/llvm/utils/TableGen/CodeGenInstruction.h
@@ -23,8 +23,6 @@
 #include <vector>
 
 namespace llvm {
-class SMLoc;
-template <typename T> class ArrayRef;
   class Record;
   class DagInit;
   class CodeGenTarget;
@@ -340,71 +338,6 @@ template <typename T> class ArrayRef;
     bool isOperandImpl(StringRef OpListName, unsigned i,
                        StringRef PropertyName) const;
   };
-
-
-  /// CodeGenInstAlias - This represents an InstAlias definition.
-  class CodeGenInstAlias {
-  public:
-    Record *TheDef;            // The actual record defining this InstAlias.
-
-    /// AsmString - The format string used to emit a .s file for the
-    /// instruction.
-    std::string AsmString;
-
-    /// Result - The result instruction.
-    DagInit *Result;
-
-    /// ResultInst - The instruction generated by the alias (decoded from
-    /// Result).
-    CodeGenInstruction *ResultInst;
-
-
-    struct ResultOperand {
-    private:
-      std::string Name;
-      Record *R = nullptr;
-      int64_t Imm = 0;
-
-    public:
-      enum {
-        K_Record,
-        K_Imm,
-        K_Reg
-      } Kind;
-
-      ResultOperand(std::string N, Record *r)
-          : Name(std::move(N)), R(r), Kind(K_Record) {}
-      ResultOperand(int64_t I) : Imm(I), Kind(K_Imm) {}
-      ResultOperand(Record *r) : R(r), Kind(K_Reg) {}
-
-      bool isRecord() const { return Kind == K_Record; }
-      bool isImm() const { return Kind == K_Imm; }
-      bool isReg() const { return Kind == K_Reg; }
-
-      StringRef getName() const { assert(isRecord()); return Name; }
-      Record *getRecord() const { assert(isRecord()); return R; }
-      int64_t getImm() const { assert(isImm()); return Imm; }
-      Record *getRegister() const { assert(isReg()); return R; }
-
-      unsigned getMINumOperands() const;
-    };
-
-    /// ResultOperands - The decoded operands for the result instruction.
-    std::vector<ResultOperand> ResultOperands;
-
-    /// ResultInstOperandIndex - For each operand, this vector holds a pair of
-    /// indices to identify the corresponding operand in the result
-    /// instruction.  The first index specifies the operand and the second
-    /// index specifies the suboperand.  If there are no suboperands or if all
-    /// of them are matched by the operand, the second value should be -1.
-    std::vector<std::pair<unsigned, int> > ResultInstOperandIndex;
-
-    CodeGenInstAlias(Record *R, CodeGenTarget &T);
-
-    bool tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
-                         Record *InstOpRec, bool hasSubOps, ArrayRef<SMLoc> Loc,
-                         CodeGenTarget &T, ResultOperand &ResOp);
-  };
-}
+} // namespace llvm
 
 #endif

diff  --git a/llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn b/llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn
index b5c774f363109..b0abe638c528a 100644
--- a/llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn
@@ -15,6 +15,7 @@ executable("llvm-tblgen") {
     "CodeEmitterGen.cpp",
     "CodeGenDAGPatterns.cpp",
     "CodeGenHwModes.cpp",
+    "CodeGenInstAlias.cpp",
     "CodeGenInstruction.cpp",
     "CodeGenMapTable.cpp",
     "CodeGenRegisters.cpp",


        


More information about the llvm-commits mailing list