//===-- llvm/CodeGen/SelectionDAGCSEMap.h - CSE Map for SD ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file was developed by Chris Lattner and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file declares the SelectionDAG class, and transitively defines the // SDNode class and subclasses. // //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_SELECTIONDAGCSEMAP_H #define LLVM_CODEGEN_SELECTIONDAGCSEMAP_H #include "llvm/ADT/SmallVector.h" namespace llvm { class SDNode; class SDOperand; struct SDVTList; /// SelectionDAGCSEMap - This class is used for two purposes: /// 1. Given information (e.g. opcode and operand info) about a node we want /// to create, look up the unique instance of the node in the map. If /// the node already exists, return it, otherwise return the bucket it /// should be inserted into. /// 2. Given a node that has already been created, remove it from the CSE /// map. /// /// This class is implemented as a chained hash table, where the "buckets" are /// actually the SDNodes themselves (the next pointer is in the SDNode). /// class SelectionDAGCSEMap { void **Buckets; unsigned NumBuckets; // Always a power of 2. unsigned NumNodes; public: class NodeID; SelectionDAGCSEMap(); ~SelectionDAGCSEMap(); /// RemoveNode - Remove a node from the CSE map, returning true if one was /// removed or false if the node was not in the CSE map. bool RemoveNode(SDNode *N); /// GetOrInsertSimpleNode - If there is an existing simple SDNode exactly /// equal to the specified node, return it. Otherwise, insert 'N' and it /// instead. This only works on *simple* SDNodes, not ConstantSDNode or any /// other classes derived from SDNode. SDNode *GetOrInsertNode(SDNode *N); /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists, /// return it. If not, return the insertion token that will make insertion /// faster. SDNode *FindNodeOrInsertPos(const NodeID &ID, void *&InsertPos); /// InsertNode - Insert the specified node into the CSE Map, knowing that it /// is not already in the map. InsertPos must be obtained from /// FindNodeOrInsertPos. void InsertNode(SDNode *N, void *InsertPos); class NodeID { /// Use a SmallVector to avoid a heap allocation in the common case. /// SmallVector Bits; public: NodeID() {} NodeID(SDNode *N); NodeID(unsigned short ID, SDVTList VTList); NodeID(unsigned short ID, SDVTList VTList, SDOperand Op); NodeID(unsigned short ID, SDVTList VTList, SDOperand Op1, SDOperand Op2); NodeID(unsigned short ID, SDVTList VTList, SDOperand Op1, SDOperand Op2, SDOperand Op3); NodeID(unsigned short ID, SDVTList VTList, const SDOperand *OpList, unsigned N); void SetOpcode(unsigned short ID) { Bits.push_back(ID); } /// getOpcode - Return the opcode that has been set for this NodeID. /// unsigned getOpcode() const { return Bits[0]; } void SetValueTypes(SDVTList VTList); void SetOperands() {} void SetOperands(SDOperand Op) { AddOperand(Op); } void SetOperands(SDOperand Op1, SDOperand Op2) { AddOperand(Op1); AddOperand(Op2); } void SetOperands(SDOperand Op1, SDOperand Op2, SDOperand Op3) { AddOperand(Op1); AddOperand(Op2); AddOperand(Op3); } void SetOperands(const SDOperand *Ops, unsigned NumOps); void AddOperand(SDOperand Op); void AddPointer(const void *Ptr); void AddInteger(signed I) { Bits.push_back(I); } void AddInteger(unsigned I) { Bits.push_back(I); } void AddInteger(uint64_t I) { Bits.push_back(unsigned(I)); Bits.push_back(unsigned(I >> 32)); } unsigned ComputeHash() const; bool operator==(const NodeID &RHS) const; }; private: SDNode *GetNextPtr(void *NextInBucketPtr); SDNode *GetNextPtr(void *NextInBucketPtr, void **Buckets, unsigned NumBuck); void **GetBucketPtr(void *NextInBucketPtr); void **GetBucketFor(const NodeID &ID) const; void GrowHashTable(); }; } // end namespace llvm #endif