/clamav-0.97.5/libclamav/c++/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
C++ | 6481 lines | 4984 code | 722 blank | 775 comment | 1430 complexity | 9213e93c9c5845cf4acc5047dc808db7 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- //===-- SelectionDAG.cpp - Implement the SelectionDAG data structures -----===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- //
- // This implements the SelectionDAG class.
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/CodeGen/SelectionDAG.h"
- #include "SDNodeOrdering.h"
- #include "SDNodeDbgValue.h"
- #include "llvm/Constants.h"
- #include "llvm/Analysis/DebugInfo.h"
- #include "llvm/Analysis/ValueTracking.h"
- #include "llvm/Function.h"
- #include "llvm/GlobalAlias.h"
- #include "llvm/GlobalVariable.h"
- #include "llvm/Intrinsics.h"
- #include "llvm/DerivedTypes.h"
- #include "llvm/Assembly/Writer.h"
- #include "llvm/CallingConv.h"
- #include "llvm/CodeGen/MachineBasicBlock.h"
- #include "llvm/CodeGen/MachineConstantPool.h"
- #include "llvm/CodeGen/MachineFrameInfo.h"
- #include "llvm/CodeGen/MachineModuleInfo.h"
- #include "llvm/CodeGen/PseudoSourceValue.h"
- #include "llvm/Target/TargetRegisterInfo.h"
- #include "llvm/Target/TargetData.h"
- #include "llvm/Target/TargetFrameInfo.h"
- #include "llvm/Target/TargetLowering.h"
- #include "llvm/Target/TargetSelectionDAGInfo.h"
- #include "llvm/Target/TargetOptions.h"
- #include "llvm/Target/TargetInstrInfo.h"
- #include "llvm/Target/TargetIntrinsicInfo.h"
- #include "llvm/Target/TargetMachine.h"
- #include "llvm/Support/CommandLine.h"
- #include "llvm/Support/Debug.h"
- #include "llvm/Support/ErrorHandling.h"
- #include "llvm/Support/ManagedStatic.h"
- #include "llvm/Support/MathExtras.h"
- #include "llvm/Support/raw_ostream.h"
- #include "llvm/System/Mutex.h"
- #include "llvm/ADT/SetVector.h"
- #include "llvm/ADT/SmallPtrSet.h"
- #include "llvm/ADT/SmallSet.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/ADT/StringExtras.h"
- #include <algorithm>
- #include <cmath>
- using namespace llvm;
- /// makeVTList - Return an instance of the SDVTList struct initialized with the
- /// specified members.
- static SDVTList makeVTList(const EVT *VTs, unsigned NumVTs) {
- SDVTList Res = {VTs, NumVTs};
- return Res;
- }
- static const fltSemantics *EVTToAPFloatSemantics(EVT VT) {
- switch (VT.getSimpleVT().SimpleTy) {
- default: llvm_unreachable("Unknown FP format");
- case MVT::f32: return &APFloat::IEEEsingle;
- case MVT::f64: return &APFloat::IEEEdouble;
- case MVT::f80: return &APFloat::x87DoubleExtended;
- case MVT::f128: return &APFloat::IEEEquad;
- case MVT::ppcf128: return &APFloat::PPCDoubleDouble;
- }
- }
- SelectionDAG::DAGUpdateListener::~DAGUpdateListener() {}
- //===----------------------------------------------------------------------===//
- // ConstantFPSDNode Class
- //===----------------------------------------------------------------------===//
- /// isExactlyValue - We don't rely on operator== working on double values, as
- /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
- /// As such, this method can be used to do an exact bit-for-bit comparison of
- /// two floating point values.
- bool ConstantFPSDNode::isExactlyValue(const APFloat& V) const {
- return getValueAPF().bitwiseIsEqual(V);
- }
- bool ConstantFPSDNode::isValueValidForType(EVT VT,
- const APFloat& Val) {
- assert(VT.isFloatingPoint() && "Can only convert between FP types");
- // PPC long double cannot be converted to any other type.
- if (VT == MVT::ppcf128 ||
- &Val.getSemantics() == &APFloat::PPCDoubleDouble)
- return false;
- // convert modifies in place, so make a copy.
- APFloat Val2 = APFloat(Val);
- bool losesInfo;
- (void) Val2.convert(*EVTToAPFloatSemantics(VT), APFloat::rmNearestTiesToEven,
- &losesInfo);
- return !losesInfo;
- }
- //===----------------------------------------------------------------------===//
- // ISD Namespace
- //===----------------------------------------------------------------------===//
- /// isBuildVectorAllOnes - Return true if the specified node is a
- /// BUILD_VECTOR where all of the elements are ~0 or undef.
- bool ISD::isBuildVectorAllOnes(const SDNode *N) {
- // Look through a bit convert.
- if (N->getOpcode() == ISD::BIT_CONVERT)
- N = N->getOperand(0).getNode();
- if (N->getOpcode() != ISD::BUILD_VECTOR) return false;
- unsigned i = 0, e = N->getNumOperands();
- // Skip over all of the undef values.
- while (i != e && N->getOperand(i).getOpcode() == ISD::UNDEF)
- ++i;
- // Do not accept an all-undef vector.
- if (i == e) return false;
- // Do not accept build_vectors that aren't all constants or which have non-~0
- // elements.
- SDValue NotZero = N->getOperand(i);
- if (isa<ConstantSDNode>(NotZero)) {
- if (!cast<ConstantSDNode>(NotZero)->isAllOnesValue())
- return false;
- } else if (isa<ConstantFPSDNode>(NotZero)) {
- if (!cast<ConstantFPSDNode>(NotZero)->getValueAPF().
- bitcastToAPInt().isAllOnesValue())
- return false;
- } else
- return false;
- // Okay, we have at least one ~0 value, check to see if the rest match or are
- // undefs.
- for (++i; i != e; ++i)
- if (N->getOperand(i) != NotZero &&
- N->getOperand(i).getOpcode() != ISD::UNDEF)
- return false;
- return true;
- }
- /// isBuildVectorAllZeros - Return true if the specified node is a
- /// BUILD_VECTOR where all of the elements are 0 or undef.
- bool ISD::isBuildVectorAllZeros(const SDNode *N) {
- // Look through a bit convert.
- if (N->getOpcode() == ISD::BIT_CONVERT)
- N = N->getOperand(0).getNode();
- if (N->getOpcode() != ISD::BUILD_VECTOR) return false;
- unsigned i = 0, e = N->getNumOperands();
- // Skip over all of the undef values.
- while (i != e && N->getOperand(i).getOpcode() == ISD::UNDEF)
- ++i;
- // Do not accept an all-undef vector.
- if (i == e) return false;
- // Do not accept build_vectors that aren't all constants or which have non-0
- // elements.
- SDValue Zero = N->getOperand(i);
- if (isa<ConstantSDNode>(Zero)) {
- if (!cast<ConstantSDNode>(Zero)->isNullValue())
- return false;
- } else if (isa<ConstantFPSDNode>(Zero)) {
- if (!cast<ConstantFPSDNode>(Zero)->getValueAPF().isPosZero())
- return false;
- } else
- return false;
- // Okay, we have at least one 0 value, check to see if the rest match or are
- // undefs.
- for (++i; i != e; ++i)
- if (N->getOperand(i) != Zero &&
- N->getOperand(i).getOpcode() != ISD::UNDEF)
- return false;
- return true;
- }
- /// isScalarToVector - Return true if the specified node is a
- /// ISD::SCALAR_TO_VECTOR node or a BUILD_VECTOR node where only the low
- /// element is not an undef.
- bool ISD::isScalarToVector(const SDNode *N) {
- if (N->getOpcode() == ISD::SCALAR_TO_VECTOR)
- return true;
- if (N->getOpcode() != ISD::BUILD_VECTOR)
- return false;
- if (N->getOperand(0).getOpcode() == ISD::UNDEF)
- return false;
- unsigned NumElems = N->getNumOperands();
- for (unsigned i = 1; i < NumElems; ++i) {
- SDValue V = N->getOperand(i);
- if (V.getOpcode() != ISD::UNDEF)
- return false;
- }
- return true;
- }
- /// getSetCCSwappedOperands - Return the operation corresponding to (Y op X)
- /// when given the operation for (X op Y).
- ISD::CondCode ISD::getSetCCSwappedOperands(ISD::CondCode Operation) {
- // To perform this operation, we just need to swap the L and G bits of the
- // operation.
- unsigned OldL = (Operation >> 2) & 1;
- unsigned OldG = (Operation >> 1) & 1;
- return ISD::CondCode((Operation & ~6) | // Keep the N, U, E bits
- (OldL << 1) | // New G bit
- (OldG << 2)); // New L bit.
- }
- /// getSetCCInverse - Return the operation corresponding to !(X op Y), where
- /// 'op' is a valid SetCC operation.
- ISD::CondCode ISD::getSetCCInverse(ISD::CondCode Op, bool isInteger) {
- unsigned Operation = Op;
- if (isInteger)
- Operation ^= 7; // Flip L, G, E bits, but not U.
- else
- Operation ^= 15; // Flip all of the condition bits.
- if (Operation > ISD::SETTRUE2)
- Operation &= ~8; // Don't let N and U bits get set.
- return ISD::CondCode(Operation);
- }
- /// isSignedOp - For an integer comparison, return 1 if the comparison is a
- /// signed operation and 2 if the result is an unsigned comparison. Return zero
- /// if the operation does not depend on the sign of the input (setne and seteq).
- static int isSignedOp(ISD::CondCode Opcode) {
- switch (Opcode) {
- default: llvm_unreachable("Illegal integer setcc operation!");
- case ISD::SETEQ:
- case ISD::SETNE: return 0;
- case ISD::SETLT:
- case ISD::SETLE:
- case ISD::SETGT:
- case ISD::SETGE: return 1;
- case ISD::SETULT:
- case ISD::SETULE:
- case ISD::SETUGT:
- case ISD::SETUGE: return 2;
- }
- }
- /// getSetCCOrOperation - Return the result of a logical OR between different
- /// comparisons of identical values: ((X op1 Y) | (X op2 Y)). This function
- /// returns SETCC_INVALID if it is not possible to represent the resultant
- /// comparison.
- ISD::CondCode ISD::getSetCCOrOperation(ISD::CondCode Op1, ISD::CondCode Op2,
- bool isInteger) {
- if (isInteger && (isSignedOp(Op1) | isSignedOp(Op2)) == 3)
- // Cannot fold a signed integer setcc with an unsigned integer setcc.
- return ISD::SETCC_INVALID;
- unsigned Op = Op1 | Op2; // Combine all of the condition bits.
- // If the N and U bits get set then the resultant comparison DOES suddenly
- // care about orderedness, and is true when ordered.
- if (Op > ISD::SETTRUE2)
- Op &= ~16; // Clear the U bit if the N bit is set.
- // Canonicalize illegal integer setcc's.
- if (isInteger && Op == ISD::SETUNE) // e.g. SETUGT | SETULT
- Op = ISD::SETNE;
- return ISD::CondCode(Op);
- }
- /// getSetCCAndOperation - Return the result of a logical AND between different
- /// comparisons of identical values: ((X op1 Y) & (X op2 Y)). This
- /// function returns zero if it is not possible to represent the resultant
- /// comparison.
- ISD::CondCode ISD::getSetCCAndOperation(ISD::CondCode Op1, ISD::CondCode Op2,
- bool isInteger) {
- if (isInteger && (isSignedOp(Op1) | isSignedOp(Op2)) == 3)
- // Cannot fold a signed setcc with an unsigned setcc.
- return ISD::SETCC_INVALID;
- // Combine all of the condition bits.
- ISD::CondCode Result = ISD::CondCode(Op1 & Op2);
- // Canonicalize illegal integer setcc's.
- if (isInteger) {
- switch (Result) {
- default: break;
- case ISD::SETUO : Result = ISD::SETFALSE; break; // SETUGT & SETULT
- case ISD::SETOEQ: // SETEQ & SETU[LG]E
- case ISD::SETUEQ: Result = ISD::SETEQ ; break; // SETUGE & SETULE
- case ISD::SETOLT: Result = ISD::SETULT ; break; // SETULT & SETNE
- case ISD::SETOGT: Result = ISD::SETUGT ; break; // SETUGT & SETNE
- }
- }
- return Result;
- }
- //===----------------------------------------------------------------------===//
- // SDNode Profile Support
- //===----------------------------------------------------------------------===//
- /// AddNodeIDOpcode - Add the node opcode to the NodeID data.
- ///
- static void AddNodeIDOpcode(FoldingSetNodeID &ID, unsigned OpC) {
- ID.AddInteger(OpC);
- }
- /// AddNodeIDValueTypes - Value type lists are intern'd so we can represent them
- /// solely with their pointer.
- static void AddNodeIDValueTypes(FoldingSetNodeID &ID, SDVTList VTList) {
- ID.AddPointer(VTList.VTs);
- }
- /// AddNodeIDOperands - Various routines for adding operands to the NodeID data.
- ///
- static void AddNodeIDOperands(FoldingSetNodeID &ID,
- const SDValue *Ops, unsigned NumOps) {
- for (; NumOps; --NumOps, ++Ops) {
- ID.AddPointer(Ops->getNode());
- ID.AddInteger(Ops->getResNo());
- }
- }
- /// AddNodeIDOperands - Various routines for adding operands to the NodeID data.
- ///
- static void AddNodeIDOperands(FoldingSetNodeID &ID,
- const SDUse *Ops, unsigned NumOps) {
- for (; NumOps; --NumOps, ++Ops) {
- ID.AddPointer(Ops->getNode());
- ID.AddInteger(Ops->getResNo());
- }
- }
- static void AddNodeIDNode(FoldingSetNodeID &ID,
- unsigned short OpC, SDVTList VTList,
- const SDValue *OpList, unsigned N) {
- AddNodeIDOpcode(ID, OpC);
- AddNodeIDValueTypes(ID, VTList);
- AddNodeIDOperands(ID, OpList, N);
- }
- /// AddNodeIDCustom - If this is an SDNode with special info, add this info to
- /// the NodeID data.
- static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
- switch (N->getOpcode()) {
- case ISD::TargetExternalSymbol:
- case ISD::ExternalSymbol:
- llvm_unreachable("Should only be used on nodes with operands");
- default: break; // Normal nodes don't need extra info.
- case ISD::TargetConstant:
- case ISD::Constant:
- ID.AddPointer(cast<ConstantSDNode>(N)->getConstantIntValue());
- break;
- case ISD::TargetConstantFP:
- case ISD::ConstantFP: {
- ID.AddPointer(cast<ConstantFPSDNode>(N)->getConstantFPValue());
- break;
- }
- case ISD::TargetGlobalAddress:
- case ISD::GlobalAddress:
- case ISD::TargetGlobalTLSAddress:
- case ISD::GlobalTLSAddress: {
- const GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
- ID.AddPointer(GA->getGlobal());
- ID.AddInteger(GA->getOffset());
- ID.AddInteger(GA->getTargetFlags());
- break;
- }
- case ISD::BasicBlock:
- ID.AddPointer(cast<BasicBlockSDNode>(N)->getBasicBlock());
- break;
- case ISD::Register:
- ID.AddInteger(cast<RegisterSDNode>(N)->getReg());
- break;
- case ISD::SRCVALUE:
- ID.AddPointer(cast<SrcValueSDNode>(N)->getValue());
- break;
- case ISD::FrameIndex:
- case ISD::TargetFrameIndex:
- ID.AddInteger(cast<FrameIndexSDNode>(N)->getIndex());
- break;
- case ISD::JumpTable:
- case ISD::TargetJumpTable:
- ID.AddInteger(cast<JumpTableSDNode>(N)->getIndex());
- ID.AddInteger(cast<JumpTableSDNode>(N)->getTargetFlags());
- break;
- case ISD::ConstantPool:
- case ISD::TargetConstantPool: {
- const ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(N);
- ID.AddInteger(CP->getAlignment());
- ID.AddInteger(CP->getOffset());
- if (CP->isMachineConstantPoolEntry())
- CP->getMachineCPVal()->AddSelectionDAGCSEId(ID);
- else
- ID.AddPointer(CP->getConstVal());
- ID.AddInteger(CP->getTargetFlags());
- break;
- }
- case ISD::LOAD: {
- const LoadSDNode *LD = cast<LoadSDNode>(N);
- ID.AddInteger(LD->getMemoryVT().getRawBits());
- ID.AddInteger(LD->getRawSubclassData());
- break;
- }
- case ISD::STORE: {
- const StoreSDNode *ST = cast<StoreSDNode>(N);
- ID.AddInteger(ST->getMemoryVT().getRawBits());
- ID.AddInteger(ST->getRawSubclassData());
- break;
- }
- case ISD::ATOMIC_CMP_SWAP:
- case ISD::ATOMIC_SWAP:
- case ISD::ATOMIC_LOAD_ADD:
- case ISD::ATOMIC_LOAD_SUB:
- case ISD::ATOMIC_LOAD_AND:
- case ISD::ATOMIC_LOAD_OR:
- case ISD::ATOMIC_LOAD_XOR:
- case ISD::ATOMIC_LOAD_NAND:
- case ISD::ATOMIC_LOAD_MIN:
- case ISD::ATOMIC_LOAD_MAX:
- case ISD::ATOMIC_LOAD_UMIN:
- case ISD::ATOMIC_LOAD_UMAX: {
- const AtomicSDNode *AT = cast<AtomicSDNode>(N);
- ID.AddInteger(AT->getMemoryVT().getRawBits());
- ID.AddInteger(AT->getRawSubclassData());
- break;
- }
- case ISD::VECTOR_SHUFFLE: {
- const ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(N);
- for (unsigned i = 0, e = N->getValueType(0).getVectorNumElements();
- i != e; ++i)
- ID.AddInteger(SVN->getMaskElt(i));
- break;
- }
- case ISD::TargetBlockAddress:
- case ISD::BlockAddress: {
- ID.AddPointer(cast<BlockAddressSDNode>(N)->getBlockAddress());
- ID.AddInteger(cast<BlockAddressSDNode>(N)->getTargetFlags());
- break;
- }
- } // end switch (N->getOpcode())
- }
- /// AddNodeIDNode - Generic routine for adding a nodes info to the NodeID
- /// data.
- static void AddNodeIDNode(FoldingSetNodeID &ID, const SDNode *N) {
- AddNodeIDOpcode(ID, N->getOpcode());
- // Add the return value info.
- AddNodeIDValueTypes(ID, N->getVTList());
- // Add the operand info.
- AddNodeIDOperands(ID, N->op_begin(), N->getNumOperands());
- // Handle SDNode leafs with special info.
- AddNodeIDCustom(ID, N);
- }
- /// encodeMemSDNodeFlags - Generic routine for computing a value for use in
- /// the CSE map that carries volatility, temporalness, indexing mode, and
- /// extension/truncation information.
- ///
- static inline unsigned
- encodeMemSDNodeFlags(int ConvType, ISD::MemIndexedMode AM, bool isVolatile,
- bool isNonTemporal) {
- assert((ConvType & 3) == ConvType &&
- "ConvType may not require more than 2 bits!");
- assert((AM & 7) == AM &&
- "AM may not require more than 3 bits!");
- return ConvType |
- (AM << 2) |
- (isVolatile << 5) |
- (isNonTemporal << 6);
- }
- //===----------------------------------------------------------------------===//
- // SelectionDAG Class
- //===----------------------------------------------------------------------===//
- /// doNotCSE - Return true if CSE should not be performed for this node.
- static bool doNotCSE(SDNode *N) {
- if (N->getValueType(0) == MVT::Flag)
- return true; // Never CSE anything that produces a flag.
- switch (N->getOpcode()) {
- default: break;
- case ISD::HANDLENODE:
- case ISD::EH_LABEL:
- return true; // Never CSE these nodes.
- }
- // Check that remaining values produced are not flags.
- for (unsigned i = 1, e = N->getNumValues(); i != e; ++i)
- if (N->getValueType(i) == MVT::Flag)
- return true; // Never CSE anything that produces a flag.
- return false;
- }
- /// RemoveDeadNodes - This method deletes all unreachable nodes in the
- /// SelectionDAG.
- void SelectionDAG::RemoveDeadNodes() {
- // Create a dummy node (which is not added to allnodes), that adds a reference
- // to the root node, preventing it from being deleted.
- HandleSDNode Dummy(getRoot());
- SmallVector<SDNode*, 128> DeadNodes;
- // Add all obviously-dead nodes to the DeadNodes worklist.
- for (allnodes_iterator I = allnodes_begin(), E = allnodes_end(); I != E; ++I)
- if (I->use_empty())
- DeadNodes.push_back(I);
- RemoveDeadNodes(DeadNodes);
- // If the root changed (e.g. it was a dead load, update the root).
- setRoot(Dummy.getValue());
- }
- /// RemoveDeadNodes - This method deletes the unreachable nodes in the
- /// given list, and any nodes that become unreachable as a result.
- void SelectionDAG::RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes,
- DAGUpdateListener *UpdateListener) {
- // Process the worklist, deleting the nodes and adding their uses to the
- // worklist.
- while (!DeadNodes.empty()) {
- SDNode *N = DeadNodes.pop_back_val();
- if (UpdateListener)
- UpdateListener->NodeDeleted(N, 0);
- // Take the node out of the appropriate CSE map.
- RemoveNodeFromCSEMaps(N);
- // Next, brutally remove the operand list. This is safe to do, as there are
- // no cycles in the graph.
- for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ) {
- SDUse &Use = *I++;
- SDNode *Operand = Use.getNode();
- Use.set(SDValue());
- // Now that we removed this operand, see if there are no uses of it left.
- if (Operand->use_empty())
- DeadNodes.push_back(Operand);
- }
- DeallocateNode(N);
- }
- }
- void SelectionDAG::RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener){
- SmallVector<SDNode*, 16> DeadNodes(1, N);
- RemoveDeadNodes(DeadNodes, UpdateListener);
- }
- void SelectionDAG::DeleteNode(SDNode *N) {
- // First take this out of the appropriate CSE map.
- RemoveNodeFromCSEMaps(N);
- // Finally, remove uses due to operands of this node, remove from the
- // AllNodes list, and delete the node.
- DeleteNodeNotInCSEMaps(N);
- }
- void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) {
- assert(N != AllNodes.begin() && "Cannot delete the entry node!");
- assert(N->use_empty() && "Cannot delete a node that is not dead!");
- // Drop all of the operands and decrement used node's use counts.
- N->DropOperands();
- DeallocateNode(N);
- }
- void SelectionDAG::DeallocateNode(SDNode *N) {
- if (N->OperandsNeedDelete)
- delete[] N->OperandList;
- // Set the opcode to DELETED_NODE to help catch bugs when node
- // memory is reallocated.
- N->NodeType = ISD::DELETED_NODE;
- NodeAllocator.Deallocate(AllNodes.remove(N));
- // Remove the ordering of this node.
- Ordering->remove(N);
- // If any of the SDDbgValue nodes refer to this SDNode, invalidate them.
- SmallVector<SDDbgValue*, 2> &DbgVals = DbgInfo->getSDDbgValues(N);
- for (unsigned i = 0, e = DbgVals.size(); i != e; ++i)
- DbgVals[i]->setIsInvalidated();
- }
- /// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that
- /// correspond to it. This is useful when we're about to delete or repurpose
- /// the node. We don't want future request for structurally identical nodes
- /// to return N anymore.
- bool SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {
- bool Erased = false;
- switch (N->getOpcode()) {
- case ISD::EntryToken:
- llvm_unreachable("EntryToken should not be in CSEMaps!");
- return false;
- case ISD::HANDLENODE: return false; // noop.
- case ISD::CONDCODE:
- assert(CondCodeNodes[cast<CondCodeSDNode>(N)->get()] &&
- "Cond code doesn't exist!");
- Erased = CondCodeNodes[cast<CondCodeSDNode>(N)->get()] != 0;
- CondCodeNodes[cast<CondCodeSDNode>(N)->get()] = 0;
- break;
- case ISD::ExternalSymbol:
- Erased = ExternalSymbols.erase(cast<ExternalSymbolSDNode>(N)->getSymbol());
- break;
- case ISD::TargetExternalSymbol: {
- ExternalSymbolSDNode *ESN = cast<ExternalSymbolSDNode>(N);
- Erased = TargetExternalSymbols.erase(
- std::pair<std::string,unsigned char>(ESN->getSymbol(),
- ESN->getTargetFlags()));
- break;
- }
- case ISD::VALUETYPE: {
- EVT VT = cast<VTSDNode>(N)->getVT();
- if (VT.isExtended()) {
- Erased = ExtendedValueTypeNodes.erase(VT);
- } else {
- Erased = ValueTypeNodes[VT.getSimpleVT().SimpleTy] != 0;
- ValueTypeNodes[VT.getSimpleVT().SimpleTy] = 0;
- }
- break;
- }
- default:
- // Remove it from the CSE Map.
- Erased = CSEMap.RemoveNode(N);
- break;
- }
- #ifndef NDEBUG
- // Verify that the node was actually in one of the CSE maps, unless it has a
- // flag result (which cannot be CSE'd) or is one of the special cases that are
- // not subject to CSE.
- if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Flag &&
- !N->isMachineOpcode() && !doNotCSE(N)) {
- N->dump(this);
- dbgs() << "\n";
- llvm_unreachable("Node is not in map!");
- }
- #endif
- return Erased;
- }
- /// AddModifiedNodeToCSEMaps - The specified node has been removed from the CSE
- /// maps and modified in place. Add it back to the CSE maps, unless an identical
- /// node already exists, in which case transfer all its users to the existing
- /// node. This transfer can potentially trigger recursive merging.
- ///
- void
- SelectionDAG::AddModifiedNodeToCSEMaps(SDNode *N,
- DAGUpdateListener *UpdateListener) {
- // For node types that aren't CSE'd, just act as if no identical node
- // already exists.
- if (!doNotCSE(N)) {
- SDNode *Existing = CSEMap.GetOrInsertNode(N);
- if (Existing != N) {
- // If there was already an existing matching node, use ReplaceAllUsesWith
- // to replace the dead one with the existing one. This can cause
- // recursive merging of other unrelated nodes down the line.
- ReplaceAllUsesWith(N, Existing, UpdateListener);
- // N is now dead. Inform the listener if it exists and delete it.
- if (UpdateListener)
- UpdateListener->NodeDeleted(N, Existing);
- DeleteNodeNotInCSEMaps(N);
- return;
- }
- }
- // If the node doesn't already exist, we updated it. Inform a listener if
- // it exists.
- if (UpdateListener)
- UpdateListener->NodeUpdated(N);
- }
- /// FindModifiedNodeSlot - Find a slot for the specified node if its operands
- /// were replaced with those specified. If this node is never memoized,
- /// return null, otherwise return a pointer to the slot it would take. If a
- /// node already exists with these operands, the slot will be non-null.
- SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N, SDValue Op,
- void *&InsertPos) {
- if (doNotCSE(N))
- return 0;
- SDValue Ops[] = { Op };
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops, 1);
- AddNodeIDCustom(ID, N);
- SDNode *Node = CSEMap.FindNodeOrInsertPos(ID, InsertPos);
- return Node;
- }
- /// FindModifiedNodeSlot - Find a slot for the specified node if its operands
- /// were replaced with those specified. If this node is never memoized,
- /// return null, otherwise return a pointer to the slot it would take. If a
- /// node already exists with these operands, the slot will be non-null.
- SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N,
- SDValue Op1, SDValue Op2,
- void *&InsertPos) {
- if (doNotCSE(N))
- return 0;
- SDValue Ops[] = { Op1, Op2 };
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops, 2);
- AddNodeIDCustom(ID, N);
- SDNode *Node = CSEMap.FindNodeOrInsertPos(ID, InsertPos);
- return Node;
- }
- /// FindModifiedNodeSlot - Find a slot for the specified node if its operands
- /// were replaced with those specified. If this node is never memoized,
- /// return null, otherwise return a pointer to the slot it would take. If a
- /// node already exists with these operands, the slot will be non-null.
- SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N,
- const SDValue *Ops,unsigned NumOps,
- void *&InsertPos) {
- if (doNotCSE(N))
- return 0;
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops, NumOps);
- AddNodeIDCustom(ID, N);
- SDNode *Node = CSEMap.FindNodeOrInsertPos(ID, InsertPos);
- return Node;
- }
- /// VerifyNodeCommon - Sanity check the given node. Aborts if it is invalid.
- static void VerifyNodeCommon(SDNode *N) {
- switch (N->getOpcode()) {
- default:
- break;
- case ISD::BUILD_PAIR: {
- EVT VT = N->getValueType(0);
- assert(N->getNumValues() == 1 && "Too many results!");
- assert(!VT.isVector() && (VT.isInteger() || VT.isFloatingPoint()) &&
- "Wrong return type!");
- assert(N->getNumOperands() == 2 && "Wrong number of operands!");
- assert(N->getOperand(0).getValueType() == N->getOperand(1).getValueType() &&
- "Mismatched operand types!");
- assert(N->getOperand(0).getValueType().isInteger() == VT.isInteger() &&
- "Wrong operand type!");
- assert(VT.getSizeInBits() == 2 * N->getOperand(0).getValueSizeInBits() &&
- "Wrong return type size");
- break;
- }
- case ISD::BUILD_VECTOR: {
- assert(N->getNumValues() == 1 && "Too many results!");
- assert(N->getValueType(0).isVector() && "Wrong return type!");
- assert(N->getNumOperands() == N->getValueType(0).getVectorNumElements() &&
- "Wrong number of operands!");
- EVT EltVT = N->getValueType(0).getVectorElementType();
- for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I)
- assert((I->getValueType() == EltVT ||
- (EltVT.isInteger() && I->getValueType().isInteger() &&
- EltVT.bitsLE(I->getValueType()))) &&
- "Wrong operand type!");
- break;
- }
- }
- }
- /// VerifySDNode - Sanity check the given SDNode. Aborts if it is invalid.
- static void VerifySDNode(SDNode *N) {
- // The SDNode allocators cannot be used to allocate nodes with fields that are
- // not present in an SDNode!
- assert(!isa<MemSDNode>(N) && "Bad MemSDNode!");
- assert(!isa<ShuffleVectorSDNode>(N) && "Bad ShuffleVectorSDNode!");
- assert(!isa<ConstantSDNode>(N) && "Bad ConstantSDNode!");
- assert(!isa<ConstantFPSDNode>(N) && "Bad ConstantFPSDNode!");
- assert(!isa<GlobalAddressSDNode>(N) && "Bad GlobalAddressSDNode!");
- assert(!isa<FrameIndexSDNode>(N) && "Bad FrameIndexSDNode!");
- assert(!isa<JumpTableSDNode>(N) && "Bad JumpTableSDNode!");
- assert(!isa<ConstantPoolSDNode>(N) && "Bad ConstantPoolSDNode!");
- assert(!isa<BasicBlockSDNode>(N) && "Bad BasicBlockSDNode!");
- assert(!isa<SrcValueSDNode>(N) && "Bad SrcValueSDNode!");
- assert(!isa<MDNodeSDNode>(N) && "Bad MDNodeSDNode!");
- assert(!isa<RegisterSDNode>(N) && "Bad RegisterSDNode!");
- assert(!isa<BlockAddressSDNode>(N) && "Bad BlockAddressSDNode!");
- assert(!isa<EHLabelSDNode>(N) && "Bad EHLabelSDNode!");
- assert(!isa<ExternalSymbolSDNode>(N) && "Bad ExternalSymbolSDNode!");
- assert(!isa<CondCodeSDNode>(N) && "Bad CondCodeSDNode!");
- assert(!isa<CvtRndSatSDNode>(N) && "Bad CvtRndSatSDNode!");
- assert(!isa<VTSDNode>(N) && "Bad VTSDNode!");
- assert(!isa<MachineSDNode>(N) && "Bad MachineSDNode!");
- VerifyNodeCommon(N);
- }
- /// VerifyMachineNode - Sanity check the given MachineNode. Aborts if it is
- /// invalid.
- static void VerifyMachineNode(SDNode *N) {
- // The MachineNode allocators cannot be used to allocate nodes with fields
- // that are not present in a MachineNode!
- // Currently there are no such nodes.
- VerifyNodeCommon(N);
- }
- /// getEVTAlignment - Compute the default alignment value for the
- /// given type.
- ///
- unsigned SelectionDAG::getEVTAlignment(EVT VT) const {
- const Type *Ty = VT == MVT::iPTR ?
- PointerType::get(Type::getInt8Ty(*getContext()), 0) :
- VT.getTypeForEVT(*getContext());
- return TLI.getTargetData()->getABITypeAlignment(Ty);
- }
- // EntryNode could meaningfully have debug info if we can find it...
- SelectionDAG::SelectionDAG(const TargetMachine &tm)
- : TM(tm), TLI(*tm.getTargetLowering()), TSI(*tm.getSelectionDAGInfo()),
- EntryNode(ISD::EntryToken, DebugLoc(), getVTList(MVT::Other)),
- Root(getEntryNode()), Ordering(0) {
- AllNodes.push_back(&EntryNode);
- Ordering = new SDNodeOrdering();
- DbgInfo = new SDDbgInfo();
- }
- void SelectionDAG::init(MachineFunction &mf) {
- MF = &mf;
- Context = &mf.getFunction()->getContext();
- }
- SelectionDAG::~SelectionDAG() {
- allnodes_clear();
- delete Ordering;
- delete DbgInfo;
- }
- void SelectionDAG::allnodes_clear() {
- assert(&*AllNodes.begin() == &EntryNode);
- AllNodes.remove(AllNodes.begin());
- while (!AllNodes.empty())
- DeallocateNode(AllNodes.begin());
- }
- void SelectionDAG::clear() {
- allnodes_clear();
- OperandAllocator.Reset();
- CSEMap.clear();
- ExtendedValueTypeNodes.clear();
- ExternalSymbols.clear();
- TargetExternalSymbols.clear();
- std::fill(CondCodeNodes.begin(), CondCodeNodes.end(),
- static_cast<CondCodeSDNode*>(0));
- std::fill(ValueTypeNodes.begin(), ValueTypeNodes.end(),
- static_cast<SDNode*>(0));
- EntryNode.UseList = 0;
- AllNodes.push_back(&EntryNode);
- Root = getEntryNode();
- Ordering->clear();
- DbgInfo->clear();
- }
- SDValue SelectionDAG::getSExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT) {
- return VT.bitsGT(Op.getValueType()) ?
- getNode(ISD::SIGN_EXTEND, DL, VT, Op) :
- getNode(ISD::TRUNCATE, DL, VT, Op);
- }
- SDValue SelectionDAG::getZExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT) {
- return VT.bitsGT(Op.getValueType()) ?
- getNode(ISD::ZERO_EXTEND, DL, VT, Op) :
- getNode(ISD::TRUNCATE, DL, VT, Op);
- }
- SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, DebugLoc DL, EVT VT) {
- assert(!VT.isVector() &&
- "getZeroExtendInReg should use the vector element type instead of "
- "the vector type!");
- if (Op.getValueType() == VT) return Op;
- unsigned BitWidth = Op.getValueType().getScalarType().getSizeInBits();
- APInt Imm = APInt::getLowBitsSet(BitWidth,
- VT.getSizeInBits());
- return getNode(ISD::AND, DL, Op.getValueType(), Op,
- getConstant(Imm, Op.getValueType()));
- }
- /// getNOT - Create a bitwise NOT operation as (XOR Val, -1).
- ///
- SDValue SelectionDAG::getNOT(DebugLoc DL, SDValue Val, EVT VT) {
- EVT EltVT = VT.getScalarType();
- SDValue NegOne =
- getConstant(APInt::getAllOnesValue(EltVT.getSizeInBits()), VT);
- return getNode(ISD::XOR, DL, VT, Val, NegOne);
- }
- SDValue SelectionDAG::getConstant(uint64_t Val, EVT VT, bool isT) {
- EVT EltVT = VT.getScalarType();
- assert((EltVT.getSizeInBits() >= 64 ||
- (uint64_t)((int64_t)Val >> EltVT.getSizeInBits()) + 1 < 2) &&
- "getConstant with a uint64_t value that doesn't fit in the type!");
- return getConstant(APInt(EltVT.getSizeInBits(), Val), VT, isT);
- }
- SDValue SelectionDAG::getConstant(const APInt &Val, EVT VT, bool isT) {
- return getConstant(*ConstantInt::get(*Context, Val), VT, isT);
- }
- SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT) {
- assert(VT.isInteger() && "Cannot create FP integer constant!");
- EVT EltVT = VT.getScalarType();
- assert(Val.getBitWidth() == EltVT.getSizeInBits() &&
- "APInt size does not match type size!");
- unsigned Opc = isT ? ISD::TargetConstant : ISD::Constant;
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0);
- ID.AddPointer(&Val);
- void *IP = 0;
- SDNode *N = NULL;
- if ((N = CSEMap.FindNodeOrInsertPos(ID, IP)))
- if (!VT.isVector())
- return SDValue(N, 0);
- if (!N) {
- N = new (NodeAllocator) ConstantSDNode(isT, &Val, EltVT);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- }
- SDValue Result(N, 0);
- if (VT.isVector()) {
- SmallVector<SDValue, 8> Ops;
- Ops.assign(VT.getVectorNumElements(), Result);
- Result = getNode(ISD::BUILD_VECTOR, DebugLoc(), VT, &Ops[0], Ops.size());
- }
- return Result;
- }
- SDValue SelectionDAG::getIntPtrConstant(uint64_t Val, bool isTarget) {
- return getConstant(Val, TLI.getPointerTy(), isTarget);
- }
- SDValue SelectionDAG::getConstantFP(const APFloat& V, EVT VT, bool isTarget) {
- return getConstantFP(*ConstantFP::get(*getContext(), V), VT, isTarget);
- }
- SDValue SelectionDAG::getConstantFP(const ConstantFP& V, EVT VT, bool isTarget){
- assert(VT.isFloatingPoint() && "Cannot create integer FP constant!");
- EVT EltVT = VT.getScalarType();
- // Do the map lookup using the actual bit pattern for the floating point
- // value, so that we don't have problems with 0.0 comparing equal to -0.0, and
- // we don't have issues with SNANs.
- unsigned Opc = isTarget ? ISD::TargetConstantFP : ISD::ConstantFP;
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0);
- ID.AddPointer(&V);
- void *IP = 0;
- SDNode *N = NULL;
- if ((N = CSEMap.FindNodeOrInsertPos(ID, IP)))
- if (!VT.isVector())
- return SDValue(N, 0);
- if (!N) {
- N = new (NodeAllocator) ConstantFPSDNode(isTarget, &V, EltVT);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- }
- SDValue Result(N, 0);
- if (VT.isVector()) {
- SmallVector<SDValue, 8> Ops;
- Ops.assign(VT.getVectorNumElements(), Result);
- // FIXME DebugLoc info might be appropriate here
- Result = getNode(ISD::BUILD_VECTOR, DebugLoc(), VT, &Ops[0], Ops.size());
- }
- return Result;
- }
- SDValue SelectionDAG::getConstantFP(double Val, EVT VT, bool isTarget) {
- EVT EltVT = VT.getScalarType();
- if (EltVT==MVT::f32)
- return getConstantFP(APFloat((float)Val), VT, isTarget);
- else if (EltVT==MVT::f64)
- return getConstantFP(APFloat(Val), VT, isTarget);
- else if (EltVT==MVT::f80 || EltVT==MVT::f128) {
- bool ignored;
- APFloat apf = APFloat(Val);
- apf.convert(*EVTToAPFloatSemantics(EltVT), APFloat::rmNearestTiesToEven,
- &ignored);
- return getConstantFP(apf, VT, isTarget);
- } else {
- assert(0 && "Unsupported type in getConstantFP");
- return SDValue();
- }
- }
- SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV, DebugLoc DL,
- EVT VT, int64_t Offset,
- bool isTargetGA,
- unsigned char TargetFlags) {
- assert((TargetFlags == 0 || isTargetGA) &&
- "Cannot set target flags on target-independent globals");
- // Truncate (with sign-extension) the offset value to the pointer size.
- EVT PTy = TLI.getPointerTy();
- unsigned BitWidth = PTy.getSizeInBits();
- if (BitWidth < 64)
- Offset = (Offset << (64 - BitWidth) >> (64 - BitWidth));
- const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
- if (!GVar) {
- // If GV is an alias then use the aliasee for determining thread-localness.
- if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
- GVar = dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(false));
- }
- unsigned Opc;
- if (GVar && GVar->isThreadLocal())
- Opc = isTargetGA ? ISD::TargetGlobalTLSAddress : ISD::GlobalTLSAddress;
- else
- Opc = isTargetGA ? ISD::TargetGlobalAddress : ISD::GlobalAddress;
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
- ID.AddPointer(GV);
- ID.AddInteger(Offset);
- ID.AddInteger(TargetFlags);
- void *IP = 0;
- if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
- SDNode *N = new (NodeAllocator) GlobalAddressSDNode(Opc, DL, GV, VT,
- Offset, TargetFlags);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getFrameIndex(int FI, EVT VT, bool isTarget) {
- unsigned Opc = isTarget ? ISD::TargetFrameIndex : ISD::FrameIndex;
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
- ID.AddInteger(FI);
- void *IP = 0;
- if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
- SDNode *N = new (NodeAllocator) FrameIndexSDNode(FI, VT, isTarget);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getJumpTable(int JTI, EVT VT, bool isTarget,
- unsigned char TargetFlags) {
- assert((TargetFlags == 0 || isTarget) &&
- "Cannot set target flags on target-independent jump tables");
- unsigned Opc = isTarget ? ISD::TargetJumpTable : ISD::JumpTable;
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
- ID.AddInteger(JTI);
- ID.AddInteger(TargetFlags);
- void *IP = 0;
- if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
- SDNode *N = new (NodeAllocator) JumpTableSDNode(JTI, VT, isTarget,
- TargetFlags);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getConstantPool(const Constant *C, EVT VT,
- unsigned Alignment, int Offset,
- bool isTarget,
- unsigned char TargetFlags) {
- assert((TargetFlags == 0 || isTarget) &&
- "Cannot set target flags on target-independent globals");
- if (Alignment == 0)
- Alignment = TLI.getTargetData()->getPrefTypeAlignment(C->getType());
- unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool;
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
- ID.AddInteger(Alignment);
- ID.AddInteger(Offset);
- ID.AddPointer(C);
- ID.AddInteger(TargetFlags);
- void *IP = 0;
- if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
- SDNode *N = new (NodeAllocator) ConstantPoolSDNode(isTarget, C, VT, Offset,
- Alignment, TargetFlags);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getConstantPool(MachineConstantPoolValue *C, EVT VT,
- unsigned Alignment, int Offset,
- bool isTarget,
- unsigned char TargetFlags) {
- assert((TargetFlags == 0 || isTarget) &&
- "Cannot set target flags on target-independent globals");
- if (Alignment == 0)
- Alignment = TLI.getTargetData()->getPrefTypeAlignment(C->getType());
- unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool;
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
- ID.AddInteger(Alignment);
- ID.AddInteger(Offset);
- C->AddSelectionDAGCSEId(ID);
- ID.AddInteger(TargetFlags);
- void *IP = 0;
- if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
- SDNode *N = new (NodeAllocator) ConstantPoolSDNode(isTarget, C, VT, Offset,
- Alignment, TargetFlags);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) {
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, ISD::BasicBlock, getVTList(MVT::Other), 0, 0);
- ID.AddPointer(MBB);
- void *IP = 0;
- if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
- SDNode *N = new (NodeAllocator) BasicBlockSDNode(MBB);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getValueType(EVT VT) {
- if (VT.isSimple() && (unsigned)VT.getSimpleVT().SimpleTy >=
- ValueTypeNodes.size())
- ValueTypeNodes.resize(VT.getSimpleVT().SimpleTy+1);
- SDNode *&N = VT.isExtended() ?
- ExtendedValueTypeNodes[VT] : ValueTypeNodes[VT.getSimpleVT().SimpleTy];
- if (N) return SDValue(N, 0);
- N = new (NodeAllocator) VTSDNode(VT);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getExternalSymbol(const char *Sym, EVT VT) {
- SDNode *&N = ExternalSymbols[Sym];
- if (N) return SDValue(N, 0);
- N = new (NodeAllocator) ExternalSymbolSDNode(false, Sym, 0, VT);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getTargetExternalSymbol(const char *Sym, EVT VT,
- unsigned char TargetFlags) {
- SDNode *&N =
- TargetExternalSymbols[std::pair<std::string,unsigned char>(Sym,
- TargetFlags)];
- if (N) return SDValue(N, 0);
- N = new (NodeAllocator) ExternalSymbolSDNode(true, Sym, TargetFlags, VT);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getCondCode(ISD::CondCode Cond) {
- if ((unsigned)Cond >= CondCodeNodes.size())
- CondCodeNodes.resize(Cond+1);
- if (CondCodeNodes[Cond] == 0) {
- CondCodeSDNode *N = new (NodeAllocator) CondCodeSDNode(Cond);
- CondCodeNodes[Cond] = N;
- AllNodes.push_back(N);
- }
- return SDValue(CondCodeNodes[Cond], 0);
- }
- // commuteShuffle - swaps the values of N1 and N2, and swaps all indices in
- // the shuffle mask M that point at N1 to point at N2, and indices that point
- // N2 to point at N1.
- static void commuteShuffle(SDValue &N1, SDValue &N2, SmallVectorImpl<int> &M) {
- std::swap(N1, N2);
- int NElts = M.size();
- for (int i = 0; i != NElts; ++i) {
- if (M[i] >= NElts)
- M[i] -= NElts;
- else if (M[i] >= 0)
- M[i] += NElts;
- }
- }
- SDValue SelectionDAG::getVectorShuffle(EVT VT, DebugLoc dl, SDValue N1,
- SDValue N2, const int *Mask) {
- assert(N1.getValueType() == N2.getValueType() && "Invalid VECTOR_SHUFFLE");
- assert(VT.isVector() && N1.getValueType().isVector() &&
- "Vector Shuffle VTs must be a vectors");
- assert(VT.getVectorElementType() == N1.getValueType().getVectorElementType()
- && "Vector Shuffle VTs must have same element type");
- // Canonicalize shuffle undef, undef -> undef
- if (N1.getOpcode() == ISD::UNDEF && N2.getOpcode() == ISD::UNDEF)
- return getUNDEF(VT);
- // Validate that all indices in Mask are within the range of the elements
- // input to the shuffle.
- unsigned NElts = VT.getVectorNumElements();
- SmallVector<int, 8> MaskVec;
- for (unsigned i = 0; i != NElts; ++i) {
- assert(Mask[i] < (int)(NElts * 2) && "Index out of range");
- MaskVec.push_back(Mask[i]);
- }
- // Canonicalize shuffle v, v -> v, undef
- if (N1 == N2) {
- N2 = getUNDEF(VT);
- for (unsigned i = 0; i != NElts; ++i)
- if (MaskVec[i] >= (int)NElts) MaskVec[i] -= NElts;
- }
- // Canonicalize shuffle undef, v -> v, undef. Commute the shuffle mask.
- if (N1.getOpcode() == ISD::UNDEF)
- commuteShuffle(N1, N2, MaskVec);
- // Canonicalize all index into lhs, -> shuffle lhs, undef
- // Canonicalize all index into rhs, -> shuffle rhs, undef
- bool AllLHS = true, AllRHS = true;
- bool N2Undef = N2.getOpcode() == ISD::UNDEF;
- for (unsigned i = 0; i != NElts; ++i) {
- if (MaskVec[i] >= (int)NElts) {
- if (N2Undef)
- MaskVec[i] = -1;
- else
- AllLHS = false;
- } else if (MaskVec[i] >= 0) {
- AllRHS = false;
- }
- }
- if (AllLHS && AllRHS)
- return getUNDEF(VT);
- if (AllLHS && !N2Undef)
- N2 = getUNDEF(VT);
- if (AllRHS) {
- N1 = getUNDEF(VT);
- commuteShuffle(N1, N2, MaskVec);
- }
- // If Identity shuffle, or all shuffle in to undef, return that node.
- bool AllUndef = true;
- bool Identity = true;
- for (unsigned i = 0; i != NElts; ++i) {
- if (MaskVec[i] >= 0 && MaskVec[i] != (int)i) Identity = false;
- if (MaskVec[i] >= 0) AllUndef = false;
- }
- if (Identity && NElts == N1.getValueType().getVectorNumElements())
- return N1;
- if (AllUndef)
- return getUNDEF(VT);
- FoldingSetNodeID ID;
- SDValue Ops[2] = { N1, N2 };
- AddNodeIDNode(ID, ISD::VECTOR_SHUFFLE, getVTList(VT), Ops, 2);
- for (unsigned i = 0; i != NElts; ++i)
- ID.AddInteger(MaskVec[i]);
- void* IP = 0;
- if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
- // Allocate the mask array for the node out of the BumpPtrAllocator, since
- // SDNode doesn't have access to it. This memory will be "leaked" when
- // the node is deallocated, but recovered when the NodeAllocator is released.
- int *MaskAlloc = OperandAllocator.Allocate<int>(NElts);
- memcpy(MaskAlloc, &MaskVec[0], NElts * sizeof(int));
- ShuffleVectorSDNode *N =
- new (NodeAllocator) ShuffleVectorSDNode(VT, dl, N1, N2, MaskAlloc);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getConvertRndSat(EVT VT, DebugLoc dl,
- SDValue Val, SDValue DTy,
- SDValue STy, SDValue Rnd, SDValue Sat,
- ISD::CvtCode Code) {
- // If the src and dest types are the same and the conversion is between
- // integer types of the same sign or two floats, no conversion is necessary.
- if (DTy == STy &&
- (Code == ISD::CVT_UU || Code == ISD::CVT_SS || Code == ISD::CVT_FF))
- return Val;
- FoldingSetNodeID ID;
- SDValue Ops[] = { Val, DTy, STy, Rnd, Sat };
- AddNodeIDNode(ID, ISD::CONVERT_RNDSAT, getVTList(VT), &Ops[0], 5);
- void* IP = 0;
- if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
- CvtRndSatSDNode *N = new (NodeAllocator) CvtRndSatSDNode(VT, dl, Ops, 5,
- Code);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getRegister(unsigned RegNo, EVT VT) {
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, ISD::Register, getVTList(VT), 0, 0);
- ID.AddInteger(RegNo);
- void *IP = 0;
- if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
- SDNode *N = new (NodeAllocator) RegisterSDNode(RegNo, VT);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getEHLabel(DebugLoc dl, SDValue Root, MCSymbol *Label) {
- FoldingSetNodeID ID;
- SDValue Ops[] = { Root };
- AddNodeIDNode(ID, ISD::EH_LABEL, getVTList(MVT::Other), &Ops[0], 1);
- ID.AddPointer(Label);
- void *IP = 0;
- if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
-
- SDNode *N = new (NodeAllocator) EHLabelSDNode(dl, Root, Label);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getBlockAddress(const BlockAddress *BA, EVT VT,
- bool isTarget,
- unsigned char TargetFlags) {
- unsigned Opc = isTarget ? ISD::TargetBlockAddress : ISD::BlockAddress;
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
- ID.AddPointer(BA);
- ID.AddInteger(TargetFlags);
- void *IP = 0;
- if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
- SDNode *N = new (NodeAllocator) BlockAddressSDNode(Opc, VT, BA, TargetFlags);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- SDValue SelectionDAG::getSrcValue(const Value *V) {
- assert((!V || V->getType()->isPointerTy()) &&
- "SrcValue is not a pointer?");
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, ISD::SRCVALUE, getVTList(MVT::Other), 0, 0);
- ID.AddPointer(V);
- void *IP = 0;
- if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
- SDNode *N = new (NodeAllocator) SrcValueSDNode(V);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- /// getMDNode - Return an MDNodeSDNode which holds an MDNode.
- SDValue SelectionDAG::getMDNode(const MDNode *MD) {
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, ISD::MDNODE_SDNODE, getVTList(MVT::Other), 0, 0);
- ID.AddPointer(MD);
-
- void *IP = 0;
- if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
- return SDValue(E, 0);
-
- SDNode *N = new (NodeAllocator) MDNodeSDNode(MD);
- CSEMap.InsertNode(N, IP);
- AllNodes.push_back(N);
- return SDValue(N, 0);
- }
- /// getShiftAmountOperand - Return the specified value casted to
- /// the target's desired shift amount type.
- SDValue SelectionDAG::getShiftAmountOperand(SDValue Op) {
- EVT OpTy = Op.getValueType();
- MVT ShTy = TLI.getShiftAmountTy();
- if (OpTy == ShTy || OpTy.isVector()) return Op;
- ISD::NodeType Opcode = OpTy.bitsGT(ShTy) ? ISD::TRUNCATE : ISD::ZERO_EXTEND;
- return getNode(Opcode, Op.getDebugLoc(), ShTy, Op);
- }
- /// CreateStackTemporary - Create a stack temporary, suitable for holding the
- /// specified value type.
- SDValue SelectionDAG::CreateStackTemporary(EVT VT, unsigned minAlign) {
- MachineFrameInfo *FrameInfo = getMa…
Large files files are truncated, but you can click here to view the full file