Reimplement BuildResultOperands to be in terms of the result instruction's
authorChris Lattner <sabre@nondot.org>
Sat, 6 Nov 2010 07:14:44 +0000 (07:14 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 6 Nov 2010 07:14:44 +0000 (07:14 +0000)
operand list instead of the operand list redundantly declared on the alias
or instruction.

With this change, we finally remove the ins/outs list on the alias.  Before:
  def : InstAlias<(outs GR16:$dst), (ins GR8 :$src),
                  "movsx $src, $dst",
                  (MOVSX16rr8W GR16:$dst, GR8:$src)>;
After:
  def : InstAlias<"movsx $src, $dst",
                  (MOVSX16rr8W GR16:$dst, GR8:$src)>;

This also makes the alias mechanism more general and powerful, which will
be exploited in subsequent patches.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118329 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/Target.td
lib/Target/X86/X86InstrInfo.td
utils/TableGen/AsmMatcherEmitter.cpp
utils/TableGen/CodeGenInstruction.cpp
utils/TableGen/CodeGenInstruction.h

index 5e955e9fd7a4079982c3d12a197e908ea65c4845..760996e3e74ab34216c5498d268ca3849d241a29 100644 (file)
@@ -570,9 +570,7 @@ class MnemonicAlias<string From, string To> {
 /// InstAlias - This defines an alternate assembly syntax that is allowed to
 /// match an instruction that has a different (more canonical) assembly
 /// representation.
-class InstAlias<dag Outs, dag Ins, string Asm, dag Result> {
-  dag OutOperandList = Outs;   // An dag containing the MI def operand list.
-  dag InOperandList = Ins;     // An dag containing the MI use operand list.
+class InstAlias<string Asm, dag Result> {
   string AsmString = Asm;      // The .s format to match the instruction with.
   dag ResultInst = Result;     // The MCInst to generate.
   
index 9908ade8c15f98b8eb7df44d3f8bbf5a6cf1d450..ad3fe1556be7b0538c5042b17b90d8e125e6065b 100644 (file)
@@ -1371,50 +1371,37 @@ defm : IntegerCondCodeMnemonicAlias<"cmov", "q">;
 //===----------------------------------------------------------------------===//
 
 // movsx aliases
-def : InstAlias<(outs GR16:$dst), (ins GR8 :$src),
-                "movsx $src, $dst",
+def : InstAlias<"movsx $src, $dst",
                 (MOVSX16rr8W GR16:$dst, GR8:$src)>;
-def : InstAlias<(outs GR16:$dst), (ins i8mem:$src),
-                "movsx $src, $dst",
+def : InstAlias<"movsx $src, $dst",
                 (MOVSX16rm8W GR16:$dst, i8mem:$src)>;
 
-def : InstAlias<(outs GR32:$dst), (ins GR8 :$src),
-                "movsx $src, $dst",
+def : InstAlias<"movsx $src, $dst",
                 (MOVSX32rr8 GR32:$dst, GR8:$src)>;
-def : InstAlias<(outs GR32:$dst), (ins GR16:$src),
-                "movsx $src, $dst",
+def : InstAlias<"movsx $src, $dst",
                 (MOVSX32rr16 GR32:$dst, GR16:$src)>;
 
-def : InstAlias<(outs GR64:$dst), (ins GR8 :$src),
-                "movsx $src, $dst",
+def : InstAlias<"movsx $src, $dst",
                 (MOVSX64rr8 GR64:$dst, GR8:$src)>;
-def : InstAlias<(outs GR64:$dst), (ins GR16:$src),
-                "movsx $src, $dst",
+def : InstAlias<"movsx $src, $dst",
                 (MOVSX64rr16 GR64:$dst, GR16:$src)>;
-def : InstAlias<(outs GR64:$dst), (ins GR32:$src),
-                "movsx $src, $dst",
+def : InstAlias<"movsx $src, $dst",
                 (MOVSX64rr32 GR64:$dst, GR32:$src)>;
 
 // movzx aliases
-def : InstAlias<(outs GR16:$dst), (ins GR8 :$src),
-                "movzx $src, $dst",
+def : InstAlias<"movzx $src, $dst",
                 (MOVZX16rr8W GR16:$dst, GR8:$src)>;
-def : InstAlias<(outs GR16:$dst), (ins i8mem:$src),
-                "movzx $src, $dst",
+def : InstAlias<"movzx $src, $dst",
                 (MOVZX16rm8W GR16:$dst, i8mem:$src)>;
 
-def : InstAlias<(outs GR32:$dst), (ins GR8 :$src),
-                "movzx $src, $dst",
+def : InstAlias<"movzx $src, $dst",
                 (MOVZX32rr8 GR32:$dst, GR8:$src)>;
-def : InstAlias<(outs GR32:$dst), (ins GR16:$src),
-                "movzx $src, $dst",
+def : InstAlias<"movzx $src, $dst",
                 (MOVZX32rr16 GR32:$dst, GR16:$src)>;
 
-def : InstAlias<(outs GR64:$dst), (ins GR8 :$src),
-                "movzx $src, $dst",
+def : InstAlias<"movzx $src, $dst",
                 (MOVZX64rr8_Q GR64:$dst, GR8:$src)>;
-def : InstAlias<(outs GR64:$dst), (ins GR16:$src),
-                "movzx $src, $dst",
+def : InstAlias<"movzx $src, $dst",
                 (MOVZX64rr16_Q GR64:$dst, GR16:$src)>;
 // Note: No GR32->GR64 movzx form.
 
index 7e6c7b6b8b59528931a575fc222327924e16d2bc..be72ab449b2197d0e7aeabd9c65be712cfff9882 100644 (file)
@@ -313,9 +313,11 @@ struct MatchableInfo {
   /// DefRec - This is the definition that it came from.
   PointerUnion<const CodeGenInstruction*, const CodeGenInstAlias*> DefRec;
   
-  // FIXME: REMOVE.
-  const CGIOperandList &TheOperandList;
-
+  const CodeGenInstruction *getResultInst() const {
+    if (DefRec.is<const CodeGenInstruction*>())
+      return DefRec.get<const CodeGenInstruction*>();
+    return DefRec.get<const CodeGenInstAlias*>()->ResultInst;
+  }
   
   /// ResOperands - This is the operand list that should be built for the result
   /// MCInst.
@@ -344,13 +346,11 @@ struct MatchableInfo {
   std::string ConversionFnKind;
   
   MatchableInfo(const CodeGenInstruction &CGI)
-    : TheDef(CGI.TheDef), DefRec(&CGI),
-      TheOperandList(CGI.Operands), AsmString(CGI.AsmString) {
+    : TheDef(CGI.TheDef), DefRec(&CGI), AsmString(CGI.AsmString) {
   }
 
   MatchableInfo(const CodeGenInstAlias *Alias)
-    : TheDef(Alias->TheDef), DefRec(Alias), TheOperandList(Alias->Operands),
-      AsmString(Alias->AsmString) {
+    : TheDef(Alias->TheDef), DefRec(Alias), AsmString(Alias->AsmString) {
   }
   
   void Initialize(const AsmMatcherInfo &Info,
@@ -1128,7 +1128,7 @@ BuildInstructionOperandReference(MatchableInfo *II,
   const CodeGenInstruction &CGI = *II->DefRec.get<const CodeGenInstruction*>();
   const CGIOperandList &Operands = CGI.Operands;
   
-  // Map this token to an operand. FIXME: Move elsewhere.
+  // Map this token to an operand.
   unsigned Idx;
   if (!Operands.hasOperandNamed(OperandName, Idx))
     throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" +
@@ -1171,6 +1171,8 @@ void AsmMatcherInfo::BuildAliasOperandReference(MatchableInfo *II,
   // Set up the operand class.
   for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i)
     if (CGA.ResultOperands[i].Name == OperandName) {
+      // It's safe to go with the first one we find, because CodeGenInstAlias
+      // validates that all operands with the same name have the same record.
       Op.Class = getOperandClass(CGA.ResultInst->Operands[i]);
       Op.SrcOpName = OperandName;
       return;
@@ -1181,8 +1183,12 @@ void AsmMatcherInfo::BuildAliasOperandReference(MatchableInfo *II,
 }
 
 void MatchableInfo::BuildResultOperands() {
-  for (unsigned i = 0, e = TheOperandList.size(); i != e; ++i) {
-    const CGIOperandList::OperandInfo &OpInfo = TheOperandList[i];
+  const CodeGenInstruction *ResultInst = getResultInst();
+  
+  // Loop over all operands of the result instruction, determining how to
+  // populate them.
+  for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
+    const CGIOperandList::OperandInfo &OpInfo = ResultInst->Operands[i];
 
     // If this is a tied operand, just copy from the previously handled operand.
     int TiedOp = OpInfo.getTiedRegister();
@@ -1794,15 +1800,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
     MatchableInfo &II = **it;
 
 
-    const CodeGenInstruction *ResultInst;
-    if (II.DefRec.is<const CodeGenInstruction*>())
-      ResultInst = II.DefRec.get<const CodeGenInstruction*>();
-    else
-      ResultInst = II.DefRec.get<const CodeGenInstAlias*>()->ResultInst;
-    
-    OS << "  { " << Target.getName() << "::" << ResultInst->TheDef->getName()
-    << ", \"" << II.Mnemonic << "\""
-    << ", " << II.ConversionFnKind << ", { ";
+    OS << "  { " << Target.getName() << "::"
+       << II.getResultInst()->TheDef->getName() << ", \"" << II.Mnemonic << "\""
+       << ", " << II.ConversionFnKind << ", { ";
     for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) {
       MatchableInfo::AsmOperand &Op = II.AsmOperands[i];
 
index a2989b116d886ecc4adcc934a1f30ee51499548e..c32a58649bdea049aeabcde8d601e0adfb0262db 100644 (file)
@@ -389,10 +389,8 @@ FlattenAsmStringVariants(StringRef Cur, unsigned Variant) {
 /// CodeGenInstAlias Implementation
 //===----------------------------------------------------------------------===//
 
-CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T)
-  : TheDef(R), Operands(R) {
+CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) {
   AsmString = R->getValueAsString("AsmString");
-
   Result = R->getValueAsDag("ResultInst");
 
   // Verify that the root of the result is an instruction.
index 625afc6bef776886d3be9f650883c8f540b39ce5..0e636a87679d278107957b956889c8331c23e357 100644 (file)
@@ -258,10 +258,6 @@ namespace llvm {
     /// instruction.
     std::string AsmString;
     
-    /// Operands - This is information about the (ins) and (outs) list specified
-    /// to the alias.
-    CGIOperandList Operands;
-    
     /// Result - The result instruction.
     DagInit *Result;