LLVM API Documentation
00001 //==-llvm/CodeGen/DAGISelHeader.h - Common DAG ISel definitions -*- C++ -*-==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file provides definitions of the common, target-independent methods and 00011 // data, which is used by SelectionDAG-based instruction selectors. 00012 // 00013 // *** NOTE: This file is #included into the middle of the target 00014 // instruction selector class. These functions are really methods. 00015 // This is a little awkward, but it allows this code to be shared 00016 // by all the targets while still being able to call into 00017 // target-specific code without using a virtual function call. 00018 // 00019 //===----------------------------------------------------------------------===// 00020 00021 #ifndef LLVM_CODEGEN_DAGISEL_HEADER_H 00022 #define LLVM_CODEGEN_DAGISEL_HEADER_H 00023 00024 /// ISelPosition - Node iterator marking the current position of 00025 /// instruction selection as it procedes through the topologically-sorted 00026 /// node list. 00027 SelectionDAG::allnodes_iterator ISelPosition; 00028 00029 /// IsChainCompatible - Returns true if Chain is Op or Chain does 00030 /// not reach Op. 00031 static bool IsChainCompatible(SDNode *Chain, SDNode *Op) { 00032 if (Chain->getOpcode() == ISD::EntryToken) 00033 return true; 00034 if (Chain->getOpcode() == ISD::TokenFactor) 00035 return false; 00036 if (Chain->getNumOperands() > 0) { 00037 SDValue C0 = Chain->getOperand(0); 00038 if (C0.getValueType() == MVT::Other) 00039 return C0.getNode() != Op && IsChainCompatible(C0.getNode(), Op); 00040 } 00041 return true; 00042 } 00043 00044 /// ISelUpdater - helper class to handle updates of the 00045 /// instruciton selection graph. 00046 class VISIBILITY_HIDDEN ISelUpdater : public SelectionDAG::DAGUpdateListener { 00047 SelectionDAG::allnodes_iterator &ISelPosition; 00048 public: 00049 explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp) 00050 : ISelPosition(isp) {} 00051 00052 /// NodeDeleted - Handle nodes deleted from the graph. If the 00053 /// node being deleted is the current ISelPosition node, update 00054 /// ISelPosition. 00055 /// 00056 virtual void NodeDeleted(SDNode *N, SDNode *E) { 00057 if (ISelPosition == SelectionDAG::allnodes_iterator(N)) 00058 ++ISelPosition; 00059 } 00060 00061 /// NodeUpdated - Ignore updates for now. 00062 virtual void NodeUpdated(SDNode *N) {} 00063 }; 00064 00065 /// ReplaceUses - replace all uses of the old node F with the use 00066 /// of the new node T. 00067 void ReplaceUses(SDValue F, SDValue T) DISABLE_INLINE { 00068 ISelUpdater ISU(ISelPosition); 00069 CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU); 00070 } 00071 00072 /// ReplaceUses - replace all uses of the old nodes F with the use 00073 /// of the new nodes T. 00074 void ReplaceUses(const SDValue *F, const SDValue *T, 00075 unsigned Num) DISABLE_INLINE { 00076 ISelUpdater ISU(ISelPosition); 00077 CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISU); 00078 } 00079 00080 /// ReplaceUses - replace all uses of the old node F with the use 00081 /// of the new node T. 00082 void ReplaceUses(SDNode *F, SDNode *T) DISABLE_INLINE { 00083 unsigned FNumVals = F->getNumValues(); 00084 unsigned TNumVals = T->getNumValues(); 00085 ISelUpdater ISU(ISelPosition); 00086 if (FNumVals != TNumVals) { 00087 for (unsigned i = 0, e = std::min(FNumVals, TNumVals); i < e; ++i) 00088 CurDAG->ReplaceAllUsesOfValueWith(SDValue(F, i), SDValue(T, i), &ISU); 00089 } else { 00090 CurDAG->ReplaceAllUsesWith(F, T, &ISU); 00091 } 00092 } 00093 00094 /// SelectRoot - Top level entry to DAG instruction selector. 00095 /// Selects instructions starting at the root of the current DAG. 00096 void SelectRoot(SelectionDAG &DAG) { 00097 SelectRootInit(); 00098 00099 // Create a dummy node (which is not added to allnodes), that adds 00100 // a reference to the root node, preventing it from being deleted, 00101 // and tracking any changes of the root. 00102 HandleSDNode Dummy(CurDAG->getRoot()); 00103 ISelPosition = next(SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode())); 00104 00105 // The AllNodes list is now topological-sorted. Visit the 00106 // nodes by starting at the end of the list (the root of the 00107 // graph) and preceding back toward the beginning (the entry 00108 // node). 00109 while (ISelPosition != CurDAG->allnodes_begin()) { 00110 SDNode *Node = --ISelPosition; 00111 // Skip dead nodes. DAGCombiner is expected to eliminate all dead nodes, 00112 // but there are currently some corner cases that it misses. Also, this 00113 // makes it theoretically possible to disable the DAGCombiner. 00114 if (Node->use_empty()) 00115 continue; 00116 #if 0 00117 DAG.setSubgraphColor(Node, "red"); 00118 #endif 00119 SDNode *ResNode = Select(SDValue(Node, 0)); 00120 // If node should not be replaced, 00121 // continue with the next one. 00122 if (ResNode == Node) 00123 continue; 00124 // Replace node. 00125 if (ResNode) { 00126 #if 0 00127 DAG.setSubgraphColor(ResNode, "yellow"); 00128 DAG.setSubgraphColor(ResNode, "black"); 00129 #endif 00130 ReplaceUses(Node, ResNode); 00131 } 00132 // If after the replacement this node is not used any more, 00133 // remove this dead node. 00134 if (Node->use_empty()) { // Don't delete EntryToken, etc. 00135 ISelUpdater ISU(ISelPosition); 00136 CurDAG->RemoveDeadNode(Node, &ISU); 00137 } 00138 } 00139 00140 CurDAG->setRoot(Dummy.getValue()); 00141 } 00142 00143 #endif /* LLVM_CODEGEN_DAGISEL_HEADER_H */