[llvm-commits] [llvm] r49123 - in /llvm/trunk/utils/TableGen: CodeGenDAGPatterns.cpp CodeGenDAGPatterns.h CodeGenIntrinsics.h CodeGenTarget.cpp CodeGenTarget.h DAGISelEmitter.h InstrInfoEmitter.cpp InstrInfoEmitter.h

Dan Gohman gohman at apple.com
Wed Apr 2 17:02:50 PDT 2008


Author: djg
Date: Wed Apr  2 19:02:49 2008
New Revision: 49123

URL: http://llvm.org/viewvc/llvm-project?rev=49123&view=rev
Log:
Move instruction flag inference out of InstrInfoEmitter and into
CodeGenDAGPatterns, where it can be used in other tablegen backends.
This allows the inference to be done for DAGISelEmitter so that it
gets accurate mayLoad/mayStore/isSimpleLoad flags. 

This brings MemOperand functionality back to where it was before
48329. However, it doesn't solve the problem of anonymous patterns
which expand to code that does loads or stores.

Modified:
    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h
    llvm/trunk/utils/TableGen/CodeGenIntrinsics.h
    llvm/trunk/utils/TableGen/CodeGenTarget.cpp
    llvm/trunk/utils/TableGen/CodeGenTarget.h
    llvm/trunk/utils/TableGen/DAGISelEmitter.h
    llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp
    llvm/trunk/utils/TableGen/InstrInfoEmitter.h

Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=49123&r1=49122&r2=49123&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Wed Apr  2 19:02:49 2008
@@ -965,7 +965,7 @@
 /// that can never possibly work), and to prevent the pattern permuter from
 /// generating stuff that is useless.
 bool TreePatternNode::canPatternMatch(std::string &Reason, 
-                                      CodeGenDAGPatterns &CDP){
+                                      const CodeGenDAGPatterns &CDP) {
   if (isLeaf()) return true;
 
   for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
@@ -1226,6 +1226,11 @@
   // Generate variants.  For example, commutative patterns can match
   // multiple ways.  Add them to PatternsToMatch as well.
   GenerateVariants();
+
+  // Infer instruction flags.  For example, we can detect loads,
+  // stores, and side effects in many cases by examining an
+  // instruction's pattern.
+  InferInstructionFlags();
 }
 
 CodeGenDAGPatterns::~CodeGenDAGPatterns() {
@@ -1558,6 +1563,131 @@
                               InstImpInputs, InstImpResults);
 }
 
+//===----------------------------------------------------------------------===//
+// Instruction Analysis
+//===----------------------------------------------------------------------===//
+
+class InstAnalyzer {
+  const CodeGenDAGPatterns &CDP;
+  bool &mayStore;
+  bool &mayLoad;
+  bool &HasSideEffects;
+public:
+  InstAnalyzer(const CodeGenDAGPatterns &cdp,
+               bool &maystore, bool &mayload, bool &hse)
+    : CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse){
+  }
+
+  /// Analyze - Analyze the specified instruction, returning true if the
+  /// instruction had a pattern.
+  bool Analyze(Record *InstRecord) {
+    const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern();
+    if (Pattern == 0) {
+      HasSideEffects = 1;
+      return false;  // No pattern.
+    }
+
+    // FIXME: Assume only the first tree is the pattern. The others are clobber
+    // nodes.
+    AnalyzeNode(Pattern->getTree(0));
+    return true;
+  }
+
+private:
+  void AnalyzeNode(const TreePatternNode *N) {
+    if (N->isLeaf()) {
+      if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
+        Record *LeafRec = DI->getDef();
+        // Handle ComplexPattern leaves.
+        if (LeafRec->isSubClassOf("ComplexPattern")) {
+          const ComplexPattern &CP = CDP.getComplexPattern(LeafRec);
+          if (CP.hasProperty(SDNPMayStore)) mayStore = true;
+          if (CP.hasProperty(SDNPMayLoad)) mayLoad = true;
+          if (CP.hasProperty(SDNPSideEffect)) HasSideEffects = true;
+        }
+      }
+      return;
+    }
+
+    // Analyze children.
+    for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
+      AnalyzeNode(N->getChild(i));
+
+    // Ignore set nodes, which are not SDNodes.
+    if (N->getOperator()->getName() == "set")
+      return;
+
+    // Get information about the SDNode for the operator.
+    const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
+
+    // Notice properties of the node.
+    if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true;
+    if (OpInfo.hasProperty(SDNPMayLoad)) mayLoad = true;
+    if (OpInfo.hasProperty(SDNPSideEffect)) HasSideEffects = true;
+
+    if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
+      // If this is an intrinsic, analyze it.
+      if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem)
+        mayLoad = true;// These may load memory.
+
+      if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem)
+        mayStore = true;// Intrinsics that can write to memory are 'mayStore'.
+
+      if (IntInfo->ModRef >= CodeGenIntrinsic::WriteMem)
+        // WriteMem intrinsics can have other strange effects.
+        HasSideEffects = true;
+    }
+  }
+
+};
+
+static void InferFromPattern(const CodeGenInstruction &Inst,
+                             bool &MayStore, bool &MayLoad,
+                             bool &HasSideEffects,
+                             const CodeGenDAGPatterns &CDP) {
+  MayStore = MayLoad = HasSideEffects = false;
+
+  bool HadPattern =
+    InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects).Analyze(Inst.TheDef);
+
+  // InstAnalyzer only correctly analyzes mayStore/mayLoad so far.
+  if (Inst.mayStore) {  // If the .td file explicitly sets mayStore, use it.
+    // If we decided that this is a store from the pattern, then the .td file
+    // entry is redundant.
+    if (MayStore)
+      fprintf(stderr,
+              "Warning: mayStore flag explicitly set on instruction '%s'"
+              " but flag already inferred from pattern.\n",
+              Inst.TheDef->getName().c_str());
+    MayStore = true;
+  }
+
+  if (Inst.mayLoad) {  // If the .td file explicitly sets mayLoad, use it.
+    // If we decided that this is a load from the pattern, then the .td file
+    // entry is redundant.
+    if (MayLoad)
+      fprintf(stderr,
+              "Warning: mayLoad flag explicitly set on instruction '%s'"
+              " but flag already inferred from pattern.\n",
+              Inst.TheDef->getName().c_str());
+    MayLoad = true;
+  }
+
+  if (Inst.neverHasSideEffects) {
+    if (HadPattern)
+      fprintf(stderr, "Warning: neverHasSideEffects set on instruction '%s' "
+              "which already has a pattern\n", Inst.TheDef->getName().c_str());
+    HasSideEffects = false;
+  }
+
+  if (Inst.hasSideEffects) {
+    if (HasSideEffects)
+      fprintf(stderr, "Warning: hasSideEffects set on instruction '%s' "
+              "which already inferred this.\n", Inst.TheDef->getName().c_str());
+    HasSideEffects = true;
+  }
+}
+
 /// ParseInstructions - Parse all of the instructions, inlining and resolving
 /// any fragments involved.  This populates the Instructions list with fully
 /// resolved instructions.
@@ -1791,6 +1921,22 @@
   }
 }
 
+
+void CodeGenDAGPatterns::InferInstructionFlags() {
+  std::map<std::string, CodeGenInstruction> &InstrDescs =
+    Target.getInstructions();
+  for (std::map<std::string, CodeGenInstruction>::iterator
+         II = InstrDescs.begin(), E = InstrDescs.end(); II != E; ++II) {
+    CodeGenInstruction &InstInfo = II->second;
+    // Determine properties of the instruction from its pattern.
+    bool MayStore, MayLoad, HasSideEffects;
+    InferFromPattern(InstInfo, MayStore, MayLoad, HasSideEffects, *this);
+    InstInfo.mayStore = MayStore;
+    InstInfo.mayLoad = MayLoad;
+    InstInfo.hasSideEffects = HasSideEffects;
+  }
+}
+
 void CodeGenDAGPatterns::ParsePatterns() {
   std::vector<Record*> Patterns = Records.getAllDerivedDefinitions("Pattern");
 

Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h?rev=49123&r1=49122&r2=49123&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h Wed Apr  2 19:02:49 2008
@@ -17,7 +17,6 @@
 
 #include <set>
 
-#include "TableGenBackend.h"
 #include "CodeGenTarget.h"
 #include "CodeGenIntrinsics.h"
 
@@ -277,7 +276,7 @@
   
   /// canPatternMatch - If it is impossible for this pattern to match on this
   /// target, fill in Reason and return false.  Otherwise, return true.
-  bool canPatternMatch(std::string &Reason, CodeGenDAGPatterns &CDP);
+  bool canPatternMatch(std::string &Reason, const CodeGenDAGPatterns &CDP);
 };
 
 
@@ -467,6 +466,7 @@
   CodeGenDAGPatterns(RecordKeeper &R); 
   ~CodeGenDAGPatterns();
   
+  CodeGenTarget &getTargetInfo() { return Target; }
   const CodeGenTarget &getTargetInfo() const { return Target; }
   
   Record *getSDNodeNamed(const std::string &Name) const;
@@ -556,6 +556,7 @@
   void ParseDefaultOperands();
   void ParseInstructions();
   void ParsePatterns();
+  void InferInstructionFlags();
   void GenerateVariants();
   
   void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,

Modified: llvm/trunk/utils/TableGen/CodeGenIntrinsics.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenIntrinsics.h?rev=49123&r1=49122&r2=49123&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenIntrinsics.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenIntrinsics.h Wed Apr  2 19:02:49 2008
@@ -49,7 +49,7 @@
     // types.
     bool isOverloaded;
 
-    CodeGenIntrinsic(Record *R, CodeGenTarget *CGT);
+    CodeGenIntrinsic(Record *R);
   };
 
   /// LoadIntrinsics - Read all of the intrinsics defined in the specified

Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=49123&r1=49122&r2=49123&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Wed Apr  2 19:02:49 2008
@@ -394,20 +394,12 @@
   
   std::vector<CodeGenIntrinsic> Result;
 
-  // If we are in the context of a target .td file, get the target info so that
-  // we can decode the current intptr_t.
-  CodeGenTarget *CGT = 0;
-  if (Records.getClass("Target") &&
-      Records.getAllDerivedDefinitions("Target").size() == 1)
-    CGT = new CodeGenTarget();
-  
   for (unsigned i = 0, e = I.size(); i != e; ++i)
-    Result.push_back(CodeGenIntrinsic(I[i], CGT));
-  delete CGT;
+    Result.push_back(CodeGenIntrinsic(I[i]));
   return Result;
 }
 
-CodeGenIntrinsic::CodeGenIntrinsic(Record *R, CodeGenTarget *CGT) {
+CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
   TheDef = R;
   std::string DefName = R->getName();
   ModRef = WriteMem;

Modified: llvm/trunk/utils/TableGen/CodeGenTarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.h?rev=49123&r1=49122&r2=49123&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenTarget.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenTarget.h Wed Apr  2 19:02:49 2008
@@ -145,6 +145,10 @@
     if (Instructions.empty()) ReadInstructions();
     return Instructions;
   }
+  std::map<std::string, CodeGenInstruction> &getInstructions() {
+    if (Instructions.empty()) ReadInstructions();
+    return Instructions;
+  }
 
   CodeGenInstruction &getInstruction(const std::string &Name) const {
     const std::map<std::string, CodeGenInstruction> &Insts = getInstructions();

Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.h?rev=49123&r1=49122&r2=49123&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelEmitter.h (original)
+++ llvm/trunk/utils/TableGen/DAGISelEmitter.h Wed Apr  2 19:02:49 2008
@@ -14,6 +14,7 @@
 #ifndef DAGISEL_EMITTER_H
 #define DAGISEL_EMITTER_H
 
+#include "TableGenBackend.h"
 #include "CodeGenDAGPatterns.h"
 #include <set>
 

Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=49123&r1=49122&r2=49123&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Wed Apr  2 19:02:49 2008
@@ -138,131 +138,6 @@
 }
 
 //===----------------------------------------------------------------------===//
-// Instruction Analysis
-//===----------------------------------------------------------------------===//
-
-class InstAnalyzer {
-  const CodeGenDAGPatterns &CDP;
-  bool &mayStore;
-  bool &mayLoad;
-  bool &HasSideEffects;
-public:
-  InstAnalyzer(const CodeGenDAGPatterns &cdp,
-               bool &maystore, bool &mayload, bool &hse)
-    : CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse){
-  }
-  
-  /// Analyze - Analyze the specified instruction, returning true if the
-  /// instruction had a pattern.
-  bool Analyze(Record *InstRecord) {
-    const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern();
-    if (Pattern == 0) {
-      HasSideEffects = 1;
-      return false;  // No pattern.
-    }
-    
-    // FIXME: Assume only the first tree is the pattern. The others are clobber
-    // nodes.
-    AnalyzeNode(Pattern->getTree(0));
-    return true;
-  }
-  
-private:
-  void AnalyzeNode(const TreePatternNode *N) {
-    if (N->isLeaf()) {
-      if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
-        Record *LeafRec = DI->getDef();
-        // Handle ComplexPattern leaves.
-        if (LeafRec->isSubClassOf("ComplexPattern")) {
-          const ComplexPattern &CP = CDP.getComplexPattern(LeafRec);
-          if (CP.hasProperty(SDNPMayStore)) mayStore = true;
-          if (CP.hasProperty(SDNPMayLoad)) mayLoad = true;
-          if (CP.hasProperty(SDNPSideEffect)) HasSideEffects = true;
-        }
-      }
-      return;
-    }
-
-    // Analyze children.
-    for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
-      AnalyzeNode(N->getChild(i));
-
-    // Ignore set nodes, which are not SDNodes.
-    if (N->getOperator()->getName() == "set")
-      return;
-    
-    // Get information about the SDNode for the operator.
-    const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
-    
-    // Notice properties of the node.
-    if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true;
-    if (OpInfo.hasProperty(SDNPMayLoad)) mayLoad = true;
-    if (OpInfo.hasProperty(SDNPSideEffect)) HasSideEffects = true;
-    
-    if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
-      // If this is an intrinsic, analyze it.
-      if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem)
-        mayLoad = true;// These may load memory.
-
-      if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem)
-        mayStore = true;// Intrinsics that can write to memory are 'mayStore'.
-
-      if (IntInfo->ModRef >= CodeGenIntrinsic::WriteMem)
-        // WriteMem intrinsics can have other strange effects.
-        HasSideEffects = true;
-    }
-  }
-  
-};
-
-void InstrInfoEmitter::InferFromPattern(const CodeGenInstruction &Inst, 
-                                        bool &MayStore, bool &MayLoad, 
-                                        bool &HasSideEffects) {
-  MayStore = MayLoad = HasSideEffects = false;
-  
-  bool HadPattern =
-    InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects).Analyze(Inst.TheDef);
-
-  // InstAnalyzer only correctly analyzes mayStore/mayLoad so far.
-  if (Inst.mayStore) {  // If the .td file explicitly sets mayStore, use it.
-    // If we decided that this is a store from the pattern, then the .td file
-    // entry is redundant.
-    if (MayStore)
-      fprintf(stderr, 
-              "Warning: mayStore flag explicitly set on instruction '%s'"
-              " but flag already inferred from pattern.\n", 
-              Inst.TheDef->getName().c_str());
-    MayStore = true;
-  }
-
-  if (Inst.mayLoad) {  // If the .td file explicitly sets mayLoad, use it.
-    // If we decided that this is a load from the pattern, then the .td file
-    // entry is redundant.
-    if (MayLoad)
-      fprintf(stderr, 
-              "Warning: mayLoad flag explicitly set on instruction '%s'"
-              " but flag already inferred from pattern.\n", 
-              Inst.TheDef->getName().c_str());
-    MayLoad = true;
-  }
-  
-  if (Inst.neverHasSideEffects) {
-    if (HadPattern)
-      fprintf(stderr, "Warning: neverHasSideEffects set on instruction '%s' "
-              "which already has a pattern\n", Inst.TheDef->getName().c_str());
-    HasSideEffects = false;
-  }
-  
-  if (Inst.hasSideEffects) {
-    if (HasSideEffects)
-      fprintf(stderr, "Warning: hasSideEffects set on instruction '%s' "
-              "which already inferred this.\n", Inst.TheDef->getName().c_str());
-    HasSideEffects = true;
-  }
-}
-
-
-//===----------------------------------------------------------------------===//
 // Main Output.
 //===----------------------------------------------------------------------===//
 
@@ -273,7 +148,7 @@
   EmitSourceFileHeader("Target Instruction Descriptors", OS);
   OS << "namespace llvm {\n\n";
 
-  CodeGenTarget Target;
+  CodeGenTarget &Target = CDP.getTargetInfo();
   const std::string &TargetName = Target.getName();
   Record *InstrInfo = Target.getInstructionSet();
 
@@ -321,10 +196,6 @@
                          std::map<std::vector<Record*>, unsigned> &EmittedLists,
                                   const OperandInfoMapTy &OpInfo,
                                   std::ostream &OS) {
-  // Determine properties of the instruction from its pattern.
-  bool mayStore, mayLoad, HasSideEffects;
-  InferFromPattern(Inst, mayStore, mayLoad, HasSideEffects);
-  
   int MinOperands = 0;
   if (!Inst.OperandList.empty())
     // Each logical operand can be multiple MI operands.
@@ -344,8 +215,8 @@
   if (Inst.hasDelaySlot) OS << "|(1<<TID::DelaySlot)";
   if (Inst.isCall)       OS << "|(1<<TID::Call)";
   if (Inst.isSimpleLoad) OS << "|(1<<TID::SimpleLoad)";
-  if (mayLoad)           OS << "|(1<<TID::MayLoad)";
-  if (mayStore)          OS << "|(1<<TID::MayStore)";
+  if (Inst.mayLoad)      OS << "|(1<<TID::MayLoad)";
+  if (Inst.mayStore)     OS << "|(1<<TID::MayStore)";
   if (Inst.isPredicable) OS << "|(1<<TID::Predicable)";
   if (Inst.isConvertibleToThreeAddress) OS << "|(1<<TID::ConvertibleTo3Addr)";
   if (Inst.isCommutable) OS << "|(1<<TID::Commutable)";
@@ -356,7 +227,7 @@
   if (Inst.usesCustomDAGSchedInserter)
     OS << "|(1<<TID::UsesCustomDAGSchedInserter)";
   if (Inst.isVariadic)         OS << "|(1<<TID::Variadic)";
-  if (HasSideEffects)          OS << "|(1<<TID::UnmodeledSideEffects)";
+  if (Inst.hasSideEffects)          OS << "|(1<<TID::UnmodeledSideEffects)";
   OS << ", 0";
 
   // Emit all of the target-specific flags...

Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.h?rev=49123&r1=49122&r2=49123&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/InstrInfoEmitter.h (original)
+++ llvm/trunk/utils/TableGen/InstrInfoEmitter.h Wed Apr  2 19:02:49 2008
@@ -29,7 +29,7 @@
 
 class InstrInfoEmitter : public TableGenBackend {
   RecordKeeper &Records;
-  const CodeGenDAGPatterns CDP;
+  CodeGenDAGPatterns CDP;
   std::map<std::string, unsigned> ItinClassMap;
   
 public:
@@ -41,10 +41,6 @@
 private:
   typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy;
   
-  // Instruction analysis.
-  void InferFromPattern(const CodeGenInstruction &Inst, 
-                        bool &MayStore, bool &MayLoad, bool &HasSideEffects);
-  
   void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
                   Record *InstrInfo, 
                   std::map<std::vector<Record*>, unsigned> &EL,





More information about the llvm-commits mailing list