[llvm-commits] [llvm] r51102 - in /llvm/trunk: include/llvm/CodeGen/DAGISelHeader.h utils/TableGen/DAGISelEmitter.cpp

Roman Levenstein romix.llvm at googlemail.com
Wed May 14 03:17:11 PDT 2008


Author: romix
Date: Wed May 14 05:17:11 2008
New Revision: 51102

URL: http://llvm.org/viewvc/llvm-project?rev=51102&view=rev
Log:
Do not generate by TableGen the hard-coded standard, target-independent part of
DAG instruction selectors. Introudce a dedicated header file for this part:
include/llvm/CodeGen/DAGISelHeader.h

TableGen now only generates the include preprocessor directive to include this
new header.

This is a preparation for supporting multiple implementations of instruction
selectors in the future.

Reviewed and approved by Evan and Dan.

Added:
    llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h
Modified:
    llvm/trunk/utils/TableGen/DAGISelEmitter.cpp

Added: llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h?rev=51102&view=auto

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h (added)
+++ llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h Wed May 14 05:17:11 2008
@@ -0,0 +1,192 @@
+//==-llvm/CodeGen/DAGISelHeader.h - Common DAG ISel definitions  -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides definitions of the common, target-independent methods and 
+// data, which is used by SelectionDAG-based instruction selectors.
+//
+// *** NOTE: This file is #included into the middle of the target
+// *** instruction selector class.  These functions are really methods.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_DAGISEL_HEADER_H
+#define LLVM_CODEGEN_DAGISEL_HEADER_H
+
+/// ISelQueue - Instruction selector priority queue sorted 
+/// in the order of increasing NodeId() values.
+std::vector<SDNode*> ISelQueue;
+
+/// Keep track of nodes which have already been added to queue.
+unsigned char *ISelQueued;
+
+/// Keep track of nodes which have already been selected.
+unsigned char *ISelSelected;
+
+/// IsChainCompatible - Returns true if Chain is Op or Chain does
+/// not reach Op.
+static bool IsChainCompatible(SDNode *Chain, SDNode *Op) {
+  if (Chain->getOpcode() == ISD::EntryToken)
+    return true;
+  else if (Chain->getOpcode() == ISD::TokenFactor)
+    return false;
+  else if (Chain->getNumOperands() > 0) {
+    SDOperand C0 = Chain->getOperand(0);
+    if (C0.getValueType() == MVT::Other)
+      return C0.Val != Op && IsChainCompatible(C0.Val, Op);
+  }
+  return true;
+}
+
+/// isel_sort - Sorting functions for the selection queue in the
+/// increasing NodeId order.
+struct isel_sort : public std::binary_function<SDNode*, SDNode*, bool> {
+  bool operator()(const SDNode* left, const SDNode* right) const {
+    return (left->getNodeId() > right->getNodeId());
+  }
+};
+
+/// setQueued - marks the node with a given NodeId() as element of the 
+/// instruction selection queue.
+inline void setQueued(int Id) {
+  ISelQueued[Id / 8] |= 1 << (Id % 8);
+}
+
+/// isSelected - checks if the node with a given NodeId() is
+/// in the instruction selection queue already.
+inline bool isQueued(int Id) {
+  return ISelQueued[Id / 8] & (1 << (Id % 8));
+}
+
+/// setSelected - marks the node with a given NodeId() as selected.
+inline void setSelected(int Id) {
+  ISelSelected[Id / 8] |= 1 << (Id % 8);
+}
+
+/// isSelected - checks if the node with a given NodeId() is
+/// selected already.
+inline bool isSelected(int Id) {
+  return ISelSelected[Id / 8] & (1 << (Id % 8));
+}
+
+/// AddToISelQueue - adds a node to the instruction 
+/// selection queue.
+void AddToISelQueue(SDOperand N) DISABLE_INLINE {
+  int Id = N.Val->getNodeId();
+  if (Id != -1 && !isQueued(Id)) {
+    ISelQueue.push_back(N.Val);
+    std::push_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());
+    setQueued(Id);
+  }
+}
+
+/// ISelQueueUpdater - helper class to handle updates of the 
+/// instruciton selection queue.
+class VISIBILITY_HIDDEN ISelQueueUpdater :
+  public SelectionDAG::DAGUpdateListener {
+    std::vector<SDNode*> &ISelQueue;
+    bool HadDelete; // Indicate if any deletions were done.
+  public:
+    explicit ISelQueueUpdater(std::vector<SDNode*> &isq)
+      : ISelQueue(isq), HadDelete(false) {}
+    
+    bool hadDelete() const { return HadDelete; }
+    
+    /// NodeDeleted - remove node from the selection queue.
+    virtual void NodeDeleted(SDNode *N) {
+      ISelQueue.erase(std::remove(ISelQueue.begin(), ISelQueue.end(), N),
+                      ISelQueue.end());
+      HadDelete = true;
+    }
+    
+    /// NodeUpdated - Ignore updates for now.
+    virtual void NodeUpdated(SDNode *N) {}
+  };
+
+/// UpdateQueue - update the instruction selction queue to maintain 
+/// the increasing NodeId() ordering property.
+inline void UpdateQueue(const ISelQueueUpdater &ISQU) {
+  if (ISQU.hadDelete())
+    std::make_heap(ISelQueue.begin(), ISelQueue.end(),isel_sort());
+}
+
+
+/// ReplaceUses - replace all uses of the old node F with the use
+/// of the new node T.
+void ReplaceUses(SDOperand F, SDOperand T) DISABLE_INLINE {
+  ISelQueueUpdater ISQU(ISelQueue);
+  CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISQU);
+  setSelected(F.Val->getNodeId());
+  UpdateQueue(ISQU);
+}
+
+/// ReplaceUses - replace all uses of the old node F with the use
+/// of the new node T.
+void ReplaceUses(SDNode *F, SDNode *T) DISABLE_INLINE {
+  unsigned FNumVals = F->getNumValues();
+  unsigned TNumVals = T->getNumValues();
+  ISelQueueUpdater ISQU(ISelQueue);
+  if (FNumVals != TNumVals) {
+    for (unsigned i = 0, e = std::min(FNumVals, TNumVals); i < e; ++i)
+     CurDAG->ReplaceAllUsesOfValueWith(SDOperand(F, i), SDOperand(T, i), &ISQU);
+  } else {
+    CurDAG->ReplaceAllUsesWith(F, T, &ISQU);
+  }
+  setSelected(F->getNodeId());
+  UpdateQueue(ISQU);
+}
+
+/// SelectRoot - Top level entry to DAG instruction selector.
+/// Selects instructions starting at the root of the current DAG.
+SDOperand SelectRoot(SDOperand Root) {
+  SelectRootInit();
+  unsigned NumBytes = (DAGSize + 7) / 8;
+  ISelQueued   = new unsigned char[NumBytes];
+  ISelSelected = new unsigned char[NumBytes];
+  memset(ISelQueued,   0, NumBytes);
+  memset(ISelSelected, 0, NumBytes);
+
+  // Create a dummy node (which is not added to allnodes), that adds
+  // a reference to the root node, preventing it from being deleted,
+  // and tracking any changes of the root.
+  HandleSDNode Dummy(CurDAG->getRoot());
+  ISelQueue.push_back(CurDAG->getRoot().Val);
+
+  // Select pending nodes from the instruction selection queue
+  // until no more nodes are left for selection.
+  while (!ISelQueue.empty()) {
+    SDNode *Node = ISelQueue.front();
+    std::pop_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());
+    ISelQueue.pop_back();
+    // Skip already selected nodes.
+    if (isSelected(Node->getNodeId()))
+      continue;
+    SDNode *ResNode = Select(SDOperand(Node, 0));
+    // If node should not be replaced, 
+    // continue with the next one.
+    if (ResNode == Node)
+      continue;
+    // Replace node.
+    if (ResNode)
+      ReplaceUses(Node, ResNode);
+    // If after the replacement this node is not used any more,
+    // remove this dead node.
+    if (Node->use_empty()) { // Don't delete EntryToken, etc.
+          ISelQueueUpdater ISQU(ISelQueue);
+          CurDAG->RemoveDeadNode(Node, &ISQU);
+          UpdateQueue(ISQU);
+    }
+  }
+
+  delete[] ISelQueued;
+  ISelQueued = NULL;
+  delete[] ISelSelected;
+  ISelSelected = NULL;
+  return Dummy.getValue();
+}
+
+#endif /* LLVM_CODEGEN_DAGISEL_HEADER_H */

Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=51102&r1=51101&r2=51102&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Wed May 14 05:17:11 2008
@@ -2011,147 +2011,10 @@
   OS << "// *** NOTE: This file is #included into the middle of the target\n"
      << "// *** instruction selector class.  These functions are really "
      << "methods.\n\n";
-  
-  OS << "// Instruction selector priority queue:\n"
-     << "std::vector<SDNode*> ISelQueue;\n";
-  OS << "/// Keep track of nodes which have already been added to queue.\n"
-     << "unsigned char *ISelQueued;\n";
-  OS << "/// Keep track of nodes which have already been selected.\n"
-     << "unsigned char *ISelSelected;\n";
-
-
-  OS << "/// IsChainCompatible - Returns true if Chain is Op or Chain does\n";
-  OS << "/// not reach Op.\n";
-  OS << "static bool IsChainCompatible(SDNode *Chain, SDNode *Op) {\n";
-  OS << "  if (Chain->getOpcode() == ISD::EntryToken)\n";
-  OS << "    return true;\n";
-  OS << "  else if (Chain->getOpcode() == ISD::TokenFactor)\n";
-  OS << "    return false;\n";
-  OS << "  else if (Chain->getNumOperands() > 0) {\n";
-  OS << "    SDOperand C0 = Chain->getOperand(0);\n";
-  OS << "    if (C0.getValueType() == MVT::Other)\n";
-  OS << "      return C0.Val != Op && IsChainCompatible(C0.Val, Op);\n";
-  OS << "  }\n";
-  OS << "  return true;\n";
-  OS << "}\n";
-
-  OS << "/// Sorting functions for the selection queue.\n"
-     << "struct isel_sort : public std::binary_function"
-     << "<SDNode*, SDNode*, bool> {\n"
-     << "  bool operator()(const SDNode* left, const SDNode* right) "
-     << "const {\n"
-     << "    return (left->getNodeId() > right->getNodeId());\n"
-     << "  }\n"
-     << "};\n\n";
-
-  OS << "inline void setQueued(int Id) {\n";
-  OS << "  ISelQueued[Id / 8] |= 1 << (Id % 8);\n";
-  OS << "}\n";
-  OS << "inline bool isQueued(int Id) {\n";
-  OS << "  return ISelQueued[Id / 8] & (1 << (Id % 8));\n";
-  OS << "}\n";
-  OS << "inline void setSelected(int Id) {\n";
-  OS << "  ISelSelected[Id / 8] |= 1 << (Id % 8);\n";
-  OS << "}\n";
-  OS << "inline bool isSelected(int Id) {\n";
-  OS << "  return ISelSelected[Id / 8] & (1 << (Id % 8));\n";
-  OS << "}\n\n";
-
-  OS << "void AddToISelQueue(SDOperand N) DISABLE_INLINE {\n";
-  OS << "  int Id = N.Val->getNodeId();\n";
-  OS << "  if (Id != -1 && !isQueued(Id)) {\n";
-  OS << "    ISelQueue.push_back(N.Val);\n";
- OS << "    std::push_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());\n";
-  OS << "    setQueued(Id);\n";
-  OS << "  }\n";
-  OS << "}\n\n";
-
-  
-  OS << "class VISIBILITY_HIDDEN ISelQueueUpdater :\n";
-  OS << "  public SelectionDAG::DAGUpdateListener {\n";
-  OS << "    std::vector<SDNode*> &ISelQueue;\n";
-  OS << "    bool HadDelete;\n";
-  OS << "  public:\n";
-  OS << "    explicit ISelQueueUpdater(std::vector<SDNode*> &isq)\n";
-  OS << "      : ISelQueue(isq), HadDelete(false) {}\n";
-  OS << "    \n";
-  OS << "    bool hadDelete() const { return HadDelete; }\n";
-  OS << "    \n";
-  OS << "    virtual void NodeDeleted(SDNode *N) {\n";
-  OS << "      ISelQueue.erase(std::remove(ISelQueue.begin(), ISelQueue.end(),";
-  OS << " N),\n                      ISelQueue.end());\n";
-  OS << "      HadDelete = true;\n";
-  OS << "    }\n";
-  OS << "    \n";
-  OS << "    // Ignore updates.\n";
-  OS << "    virtual void NodeUpdated(SDNode *N) {}\n";
-  OS << "  };\n";
-  
-  OS << "inline void UpdateQueue(const ISelQueueUpdater &ISQU) {\n";
-  OS << "  if (ISQU.hadDelete())\n";
-  OS << "    std::make_heap(ISelQueue.begin(), ISelQueue.end(),isel_sort());\n";
-  OS << "}\n\n";
-
-  OS << "void ReplaceUses(SDOperand F, SDOperand T) DISABLE_INLINE {\n";
-  OS << "  ISelQueueUpdater ISQU(ISelQueue);\n";
-  OS << "  CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISQU);\n";
-  OS << "  setSelected(F.Val->getNodeId());\n";
-  OS << "  UpdateQueue(ISQU);\n";
-  OS << "}\n";
-  OS << "void ReplaceUses(SDNode *F, SDNode *T) DISABLE_INLINE {\n";
-  OS << "  unsigned FNumVals = F->getNumValues();\n";
-  OS << "  unsigned TNumVals = T->getNumValues();\n";
-  OS << "  ISelQueueUpdater ISQU(ISelQueue);\n";
-  OS << "  if (FNumVals != TNumVals) {\n";
-  OS << "    for (unsigned i = 0, e = std::min(FNumVals, TNumVals); "
-     << "i < e; ++i)\n";
-  OS << "      CurDAG->ReplaceAllUsesOfValueWith(SDOperand(F, i), "
-     << "SDOperand(T, i), &ISQU);\n";
-  OS << "  } else {\n";
-  OS << "    CurDAG->ReplaceAllUsesWith(F, T, &ISQU);\n";
-  OS << "  }\n";
-  OS << "  setSelected(F->getNodeId());\n";
-  OS << "  UpdateQueue(ISQU);\n";
-  OS << "}\n\n";
 
-  OS << "// SelectRoot - Top level entry to DAG isel.\n";
-  OS << "SDOperand SelectRoot(SDOperand Root) {\n";
-  OS << "  SelectRootInit();\n";
-  OS << "  unsigned NumBytes = (DAGSize + 7) / 8;\n";
-  OS << "  ISelQueued   = new unsigned char[NumBytes];\n";
-  OS << "  ISelSelected = new unsigned char[NumBytes];\n";
-  OS << "  memset(ISelQueued,   0, NumBytes);\n";
-  OS << "  memset(ISelSelected, 0, NumBytes);\n";
-  OS << "\n";
-  OS << "  // Create a dummy node (which is not added to allnodes), that adds\n"
-     << "  // a reference to the root node, preventing it from being deleted,\n"
-     << "  // and tracking any changes of the root.\n"
-     << "  HandleSDNode Dummy(CurDAG->getRoot());\n"
-     << "  ISelQueue.push_back(CurDAG->getRoot().Val);\n";
-  OS << "  while (!ISelQueue.empty()) {\n";
-  OS << "    SDNode *Node = ISelQueue.front();\n";
-  OS << "    std::pop_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());\n";
-  OS << "    ISelQueue.pop_back();\n";
-  OS << "    if (!isSelected(Node->getNodeId())) {\n";
-  OS << "      SDNode *ResNode = Select(SDOperand(Node, 0));\n";
-  OS << "      if (ResNode != Node) {\n";
-  OS << "        if (ResNode)\n";
-  OS << "          ReplaceUses(Node, ResNode);\n";
-  OS << "        if (Node->use_empty()) { // Don't delete EntryToken, etc.\n";
-  OS << "          ISelQueueUpdater ISQU(ISelQueue);\n";
-  OS << "          CurDAG->RemoveDeadNode(Node, &ISQU);\n";
-  OS << "          UpdateQueue(ISQU);\n";
-  OS << "        }\n";
-  OS << "      }\n";
-  OS << "    }\n";
-  OS << "  }\n";
-  OS << "\n";
-  OS << "  delete[] ISelQueued;\n";
-  OS << "  ISelQueued = NULL;\n";
-  OS << "  delete[] ISelSelected;\n";
-  OS << "  ISelSelected = NULL;\n";
-  OS << "  return Dummy.getValue();\n";
-  OS << "}\n";
+  OS << "// Include standard, target-independent definitions and methods used\n"
+     << "// by the instruction selector.\n";
+  OS << "#include <llvm/CodeGen/DAGISelHeader.h>\n\n";
   
   EmitNodeTransforms(OS);
   EmitPredicateFunctions(OS);





More information about the llvm-commits mailing list