[llvm-commits] [llvm] r108677 - in /llvm/trunk: include/llvm/Target/TargetAsmParser.h lib/MC/MCParser/TargetAsmParser.cpp lib/Target/X86/AsmParser/X86AsmParser.cpp utils/TableGen/AsmMatcherEmitter.cpp

Daniel Dunbar daniel at zuster.org
Sun Jul 18 22:44:09 PDT 2010


Author: ddunbar
Date: Mon Jul 19 00:44:09 2010
New Revision: 108677

URL: http://llvm.org/viewvc/llvm-project?rev=108677&view=rev
Log:
TblGen/AsmMatcher: Add support for honoring instruction Requires<[]> attributes as part of the matcher.
 - Currently includes a hack to limit ourselves to "In32BitMode" and "In64BitMode", because we don't have the other infrastructure to properly deal with setting SSE, etc. features on X86.

Modified:
    llvm/trunk/include/llvm/Target/TargetAsmParser.h
    llvm/trunk/lib/MC/MCParser/TargetAsmParser.cpp
    llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp

Modified: llvm/trunk/include/llvm/Target/TargetAsmParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmParser.h?rev=108677&r1=108676&r2=108677&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetAsmParser.h (original)
+++ llvm/trunk/include/llvm/Target/TargetAsmParser.h Mon Jul 19 00:44:09 2010
@@ -28,14 +28,20 @@
 protected: // Can only create subclasses.
   TargetAsmParser(const Target &);
  
-  /// TheTarget - The Target that this machine was created for.
+  /// The Target that this machine was created for.
   const Target &TheTarget;
 
+  /// The current set of available features.
+  unsigned AvailableFeatures;
+
 public:
   virtual ~TargetAsmParser();
 
   const Target &getTarget() const { return TheTarget; }
 
+  unsigned getAvailableFeatures() const { return AvailableFeatures; }
+  void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
+
   /// ParseInstruction - Parse one assembly instruction.
   ///
   /// The parser is positioned following the instruction name. The target

Modified: llvm/trunk/lib/MC/MCParser/TargetAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/TargetAsmParser.cpp?rev=108677&r1=108676&r2=108677&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/TargetAsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/TargetAsmParser.cpp Mon Jul 19 00:44:09 2010
@@ -11,7 +11,7 @@
 using namespace llvm;
 
 TargetAsmParser::TargetAsmParser(const Target &T) 
-  : TheTarget(T)
+  : TheTarget(T), AvailableFeatures(0)
 {
 }
 

Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=108677&r1=108676&r2=108677&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Mon Jul 19 00:44:09 2010
@@ -9,6 +9,7 @@
 
 #include "llvm/Target/TargetAsmParser.h"
 #include "X86.h"
+#include "X86Subtarget.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Twine.h"
@@ -51,12 +52,14 @@
 
   void InstructionCleanup(MCInst &Inst);
 
-  /// @name Auto-generated Match Functions
-  /// {
-
   bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
                         MCInst &Inst);
 
+  /// @name Auto-generated Matcher Functions
+  /// {
+
+  unsigned ComputeAvailableFeatures(const X86Subtarget *Subtarget) const;
+
   bool MatchInstructionImpl(
     const SmallVectorImpl<MCParsedAsmOperand*> &Operands, MCInst &Inst);
 
@@ -64,7 +67,12 @@
 
 public:
   X86ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
-    : TargetAsmParser(T), Parser(_Parser), TM(TM) {}
+    : TargetAsmParser(T), Parser(_Parser), TM(TM) {
+
+    // Initialize the set of available features.
+    setAvailableFeatures(ComputeAvailableFeatures(
+                           &TM.getSubtarget<X86Subtarget>()));
+  }
 
   virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
                                 SmallVectorImpl<MCParsedAsmOperand*> &Operands);

Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=108677&r1=108676&r2=108677&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Mon Jul 19 00:44:09 2010
@@ -271,6 +271,8 @@
 
 namespace {
 
+struct SubtargetFeatureInfo;
+
 /// ClassInfo - Helper class for storing the information about a particular
 /// class of operands which can be matched.
 struct ClassInfo {
@@ -444,6 +446,9 @@
   /// Operands - The operands that this instruction matches.
   SmallVector<Operand, 4> Operands;
 
+  /// Predicates - The required subtarget features to match this instruction.
+  SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures;
+
   /// ConversionFnKind - The enum value which is passed to the generated
   /// ConvertToMCInst to convert parsed operands into an MCInst for this
   /// function.
@@ -505,6 +510,19 @@
   void dump();
 };
 
+/// SubtargetFeatureInfo - Helper class for storing information on a subtarget
+/// feature which participates in instruction matching.
+struct SubtargetFeatureInfo {
+  /// \brief The predicate record for this feature.
+  Record *TheDef;
+
+  /// \brief An unique index assigned to represent this feature.
+  unsigned Index;
+
+  /// \brief The name of the enumerated constant identifying this feature.
+  std::string EnumName;
+};
+
 class AsmMatcherInfo {
 public:
   /// The tablegen AsmParser record.
@@ -525,6 +543,9 @@
   /// Map of Register records to their class information.
   std::map<Record*, ClassInfo*> RegisterClasses;
 
+  /// Map of Predicate records to their subtarget information.
+  std::map<Record*, SubtargetFeatureInfo*> SubtargetFeatures;
+
 private:
   /// Map of token to class information which has already been constructed.
   std::map<std::string, ClassInfo*> TokenClasses;
@@ -543,6 +564,23 @@
   ClassInfo *getOperandClass(StringRef Token,
                              const CodeGenInstruction::OperandInfo &OI);
 
+  /// getSubtargetFeature - Lookup or create the subtarget feature info for the
+  /// given operand.
+  SubtargetFeatureInfo *getSubtargetFeature(Record *Def) {
+    assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!");
+
+    SubtargetFeatureInfo *&Entry = SubtargetFeatures[Def];
+    if (!Entry) {
+      Entry = new SubtargetFeatureInfo;
+      Entry->TheDef = Def;
+      Entry->Index = SubtargetFeatures.size() - 1;
+      Entry->EnumName = "Feature_" + Def->getName();
+      assert(Entry->Index < 32 && "Too many subtarget features!");
+    }
+
+    return Entry;
+  }
+
   /// BuildRegisterClasses - Build the ClassInfo* instances for register
   /// classes.
   void BuildRegisterClasses(CodeGenTarget &Target, 
@@ -903,7 +941,31 @@
         }
       }
     }
-    
+
+    // Compute the require features.
+    ListInit *Predicates = CGI.TheDef->getValueAsListInit("Predicates");
+    for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
+      if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
+        // Ignore OptForSize and OptForSpeed, they aren't really requirements,
+        // rather they are hints to isel.
+        //
+        // FIXME: Find better way to model this.
+        if (Pred->getDef()->getName() == "OptForSize" ||
+            Pred->getDef()->getName() == "OptForSpeed")
+          continue;
+
+        // FIXME: Total hack; for now, we just limit ourselves to In32BitMode
+        // and In64BitMode, because we aren't going to have the right feature
+        // masks for SSE and friends. We need to decide what we are going to do
+        // about CPU subtypes to implement this the right way.
+        if (Pred->getDef()->getName() != "In32BitMode" &&
+            Pred->getDef()->getName() != "In64BitMode")
+          continue;
+
+        II->RequiredFeatures.push_back(getSubtargetFeature(Pred->getDef()));
+      }
+    }
+
     Instructions.push_back(II.take());
   }
 
@@ -1499,6 +1561,48 @@
   OS << "}\n\n";
 }
 
+/// EmitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag
+/// definitions.
+static void EmitSubtargetFeatureFlagEnumeration(CodeGenTarget &Target,
+                                                AsmMatcherInfo &Info,
+                                                raw_ostream &OS) {
+  OS << "// Flags for subtarget features that participate in "
+     << "instruction matching.\n";
+  OS << "enum SubtargetFeatureFlag {\n";
+  for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
+         it = Info.SubtargetFeatures.begin(),
+         ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
+    SubtargetFeatureInfo &SFI = *it->second;
+    OS << "  " << SFI.EnumName << " = (1 << " << SFI.Index << "),\n";
+  }
+  OS << "  Feature_None = 0\n";
+  OS << "};\n\n";
+}
+
+/// EmitComputeAvailableFeatures - Emit the function to compute the list of
+/// available features given a subtarget.
+static void EmitComputeAvailableFeatures(CodeGenTarget &Target,
+                                         AsmMatcherInfo &Info,
+                                         raw_ostream &OS) {
+  std::string ClassName =
+    Info.AsmParser->getValueAsString("AsmParserClassName");
+
+  OS << "unsigned " << Target.getName() << ClassName << "::\n"
+     << "ComputeAvailableFeatures(const " << Target.getName()
+     << "Subtarget *Subtarget) const {\n";
+  OS << "  unsigned Features = 0;\n";
+  for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
+         it = Info.SubtargetFeatures.begin(),
+         ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
+    SubtargetFeatureInfo &SFI = *it->second;
+    OS << "  if (" << SFI.TheDef->getValueAsString("CondString")
+       << ")\n";
+    OS << "    Features |= " << SFI.EnumName << ";\n";
+  }
+  OS << "  return Features;\n";
+  OS << "}\n\n";
+}
+
 void AsmMatcherEmitter::run(raw_ostream &OS) {
   CodeGenTarget Target;
   Record *AsmParser = Target.getAsmParser();
@@ -1550,6 +1654,9 @@
 
   EmitSourceFileHeader("Assembly Matcher Source Fragment", OS);
 
+  // Emit the subtarget feature enumeration.
+  EmitSubtargetFeatureFlagEnumeration(Target, Info, OS);
+
   // Emit the function to match a register name to number.
   EmitMatchRegisterName(Target, AsmParser, OS);
   
@@ -1570,6 +1677,9 @@
   // Emit the subclass predicate routine.
   EmitIsSubclass(Target, Info.Classes, OS);
 
+  // Emit the available features compute function.
+  EmitComputeAvailableFeatures(Target, Info, OS);
+
   // Finally, build the match function.
 
   size_t MaxNumOperands = 0;
@@ -1600,6 +1710,7 @@
   OS << "    unsigned Opcode;\n";
   OS << "    ConversionKind ConvertFn;\n";
   OS << "    MatchClassKind Classes[" << MaxNumOperands << "];\n";
+  OS << "    unsigned RequiredFeatures;\n";
   OS << "  } MatchTable[" << Info.Instructions.size() << "] = {\n";
 
   for (std::vector<InstructionInfo*>::const_iterator it =
@@ -1615,11 +1726,27 @@
       if (i) OS << ", ";
       OS << Op.Class->Name;
     }
-    OS << " } },\n";
+    OS << " }, ";
+
+    // Write the required features mask.
+    if (!II.RequiredFeatures.empty()) {
+      for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
+        if (i) OS << "|";
+        OS << II.RequiredFeatures[i]->EnumName;
+      }
+    } else
+      OS << "0";
+
+    OS << "},\n";
   }
 
   OS << "  };\n\n";
 
+
+  // Emit code to get the available features.
+  OS << "  // Get the current feature set.\n";
+  OS << "  unsigned AvailableFeatures = getAvailableFeatures();\n\n";
+
   // Emit code to compute the class list for this operand vector.
   OS << "  // Eliminate obvious mismatches.\n";
   OS << "  if (Operands.size() > " << MaxNumOperands << ")\n";
@@ -1645,6 +1772,13 @@
   OS << "  for (const MatchEntry *it = MatchTable, "
      << "*ie = MatchTable + " << Info.Instructions.size()
      << "; it != ie; ++it) {\n";
+
+  // Emit check that the required features are available.
+    OS << "    if ((AvailableFeatures & it->RequiredFeatures) "
+       << "!= it->RequiredFeatures)\n";
+    OS << "      continue;\n";
+
+  // Emit check that the subclasses match.
   for (unsigned i = 0; i != MaxNumOperands; ++i) {
     OS << "    if (!IsSubclass(Classes[" 
        << i << "], it->Classes[" << i << "]))\n";





More information about the llvm-commits mailing list