mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63214 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			144 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //==-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.
 | |
| // This is a little awkward, but it allows this code to be shared
 | |
| // by all the targets while still being able to call into
 | |
| // target-specific code without using a virtual function call.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef LLVM_CODEGEN_DAGISEL_HEADER_H
 | |
| #define LLVM_CODEGEN_DAGISEL_HEADER_H
 | |
| 
 | |
| /// ISelPosition - Node iterator marking the current position of
 | |
| /// instruction selection as it procedes through the topologically-sorted
 | |
| /// node list.
 | |
| SelectionDAG::allnodes_iterator ISelPosition;
 | |
| 
 | |
| /// 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;
 | |
|   if (Chain->getOpcode() == ISD::TokenFactor)
 | |
|     return false;
 | |
|   if (Chain->getNumOperands() > 0) {
 | |
|     SDValue C0 = Chain->getOperand(0);
 | |
|     if (C0.getValueType() == MVT::Other)
 | |
|       return C0.getNode() != Op && IsChainCompatible(C0.getNode(), Op);
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| /// ISelUpdater - helper class to handle updates of the 
 | |
| /// instruciton selection graph.
 | |
| class VISIBILITY_HIDDEN ISelUpdater : public SelectionDAG::DAGUpdateListener {
 | |
|   SelectionDAG::allnodes_iterator &ISelPosition;
 | |
| public:
 | |
|   explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp)
 | |
|     : ISelPosition(isp) {}
 | |
|   
 | |
|   /// NodeDeleted - Handle nodes deleted from the graph. If the
 | |
|   /// node being deleted is the current ISelPosition node, update
 | |
|   /// ISelPosition.
 | |
|   ///
 | |
|   virtual void NodeDeleted(SDNode *N, SDNode *E) {
 | |
|     if (ISelPosition == SelectionDAG::allnodes_iterator(N))
 | |
|       ++ISelPosition;
 | |
|   }
 | |
| 
 | |
|   /// NodeUpdated - Ignore updates for now.
 | |
|   virtual void NodeUpdated(SDNode *N) {}
 | |
| };
 | |
| 
 | |
| /// ReplaceUses - replace all uses of the old node F with the use
 | |
| /// of the new node T.
 | |
| void ReplaceUses(SDValue F, SDValue T) DISABLE_INLINE {
 | |
|   ISelUpdater ISU(ISelPosition);
 | |
|   CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU);
 | |
| }
 | |
| 
 | |
| /// ReplaceUses - replace all uses of the old nodes F with the use
 | |
| /// of the new nodes T.
 | |
| void ReplaceUses(const SDValue *F, const SDValue *T,
 | |
|                  unsigned Num) DISABLE_INLINE {
 | |
|   ISelUpdater ISU(ISelPosition);
 | |
|   CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISU);
 | |
| }
 | |
| 
 | |
| /// 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();
 | |
|   ISelUpdater ISU(ISelPosition);
 | |
|   if (FNumVals != TNumVals) {
 | |
|     for (unsigned i = 0, e = std::min(FNumVals, TNumVals); i < e; ++i)
 | |
|      CurDAG->ReplaceAllUsesOfValueWith(SDValue(F, i), SDValue(T, i), &ISU);
 | |
|   } else {
 | |
|     CurDAG->ReplaceAllUsesWith(F, T, &ISU);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /// SelectRoot - Top level entry to DAG instruction selector.
 | |
| /// Selects instructions starting at the root of the current DAG.
 | |
| void SelectRoot(SelectionDAG &DAG) {
 | |
|   SelectRootInit();
 | |
| 
 | |
|   // 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());
 | |
|   ISelPosition = next(SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode()));
 | |
| 
 | |
|   // The AllNodes list is now topological-sorted. Visit the
 | |
|   // nodes by starting at the end of the list (the root of the
 | |
|   // graph) and preceding back toward the beginning (the entry
 | |
|   // node).
 | |
|   while (ISelPosition != CurDAG->allnodes_begin()) {
 | |
|     SDNode *Node = --ISelPosition;
 | |
|     // Skip dead nodes. DAGCombiner is expected to eliminate all dead nodes,
 | |
|     // but there are currently some corner cases that it misses. Also, this
 | |
|     // makes it theoretically possible to disable the DAGCombiner.
 | |
|     if (Node->use_empty())
 | |
|       continue;
 | |
| #if 0
 | |
|     DAG.setSubgraphColor(Node, "red");
 | |
| #endif
 | |
|     SDNode *ResNode = Select(SDValue(Node, 0));
 | |
|     // If node should not be replaced, 
 | |
|     // continue with the next one.
 | |
|     if (ResNode == Node)
 | |
|       continue;
 | |
|     // Replace node.
 | |
|     if (ResNode) {
 | |
| #if 0
 | |
|       DAG.setSubgraphColor(ResNode, "yellow");
 | |
|       DAG.setSubgraphColor(ResNode, "black");
 | |
| #endif
 | |
|       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.
 | |
|       ISelUpdater ISU(ISelPosition);
 | |
|       CurDAG->RemoveDeadNode(Node, &ISU);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   CurDAG->setRoot(Dummy.getValue());
 | |
| }
 | |
| 
 | |
| #endif /* LLVM_CODEGEN_DAGISEL_HEADER_H */
 |