X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FSelectionDAG.cpp;h=758f112f78c6e83e4318b50f7c67da32ed994792;hb=ee4c619b3b28a42078fc8033e5dccd42fc6edd42;hp=37297d6dccd448bfb2cbf625d7be26bfdbb21661;hpb=fd8ca5a0ef30604b860100d13544c5d5625c0b70;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 37297d6dccd..758f112f78c 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -41,11 +41,6 @@ #include using namespace llvm; -static cl::opt -NoBuiltin("no-builtin", cl::init(false), - cl::desc("Don't recognize built-in functions that do not begin " - "with `__builtin_' as prefix")); - /// makeVTList - Return an instance of the SDVTList struct initialized with the /// specified members. static SDVTList makeVTList(const MVT *VTs, unsigned NumVTs) { @@ -89,8 +84,10 @@ bool ConstantFPSDNode::isValueValidForType(MVT VT, // convert modifies in place, so make a copy. APFloat Val2 = APFloat(Val); - return Val2.convert(*MVTToAPFloatSemantics(VT), - APFloat::rmNearestTiesToEven) == APFloat::opOK; + bool losesInfo; + (void) Val2.convert(*MVTToAPFloatSemantics(VT), APFloat::rmNearestTiesToEven, + &losesInfo); + return !losesInfo; } //===----------------------------------------------------------------------===// @@ -123,7 +120,7 @@ bool ISD::isBuildVectorAllOnes(const SDNode *N) { return false; } else if (isa(NotZero)) { if (!cast(NotZero)->getValueAPF(). - convertToAPInt().isAllOnesValue()) + bitcastToAPInt().isAllOnesValue()) return false; } else return false; @@ -219,7 +216,7 @@ ISD::CondCode ISD::getSetCCSwappedOperands(ISD::CondCode Operation) { 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. + (OldG << 2)); // New L bit. } /// getSetCCInverse - Return the operation corresponding to !(X op Y), where @@ -230,8 +227,10 @@ ISD::CondCode ISD::getSetCCInverse(ISD::CondCode Op, bool 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. + Operation &= ~8; // Don't let N and U bits get set. + return ISD::CondCode(Operation); } @@ -509,7 +508,8 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, const SDNode *N) { /// encodeMemSDNodeFlags - Generic routine for computing a value for use in /// the CSE map that carries both alignment and volatility information. /// -static unsigned encodeMemSDNodeFlags(bool isVolatile, unsigned Alignment) { +static inline unsigned +encodeMemSDNodeFlags(bool isVolatile, unsigned Alignment) { return isVolatile | ((Log2_32(Alignment) + 1) << 1); } @@ -564,9 +564,10 @@ void SelectionDAG::RemoveDeadNodes(SmallVectorImpl &DeadNodes, if (Operand->use_empty()) DeadNodes.push_back(Operand); } - if (N->OperandsNeedDelete) { + + if (N->OperandsNeedDelete) delete[] N->OperandList; - } + N->OperandList = 0; N->NumOperands = 0; @@ -592,12 +593,14 @@ void SelectionDAG::DeleteNode(SDNode *N) { } void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) { - // Drop all of the operands and decrement used node's use counts. for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) I->getVal()->removeUser(std::distance(N->op_begin(), I), N); - if (N->OperandsNeedDelete) + + if (N->OperandsNeedDelete) { delete[] N->OperandList; + N->OperandList = 0; + } assert(N != AllNodes.begin()); NodeAllocator.Deallocate(AllNodes.remove(N)); @@ -678,13 +681,13 @@ SDNode *SelectionDAG::AddNonLeafNodeToCSEMaps(SDNode *N) { case ISD::DBG_STOPPOINT: case ISD::EH_LABEL: case ISD::DECLARE: - return 0; // Never add these nodes. + return 0; // Never add 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 0; // Never CSE anything that produces a flag. + return 0; // Never CSE anything that produces a flag. SDNode *New = CSEMap.GetOrInsertNode(N); if (New != N) return New; // Node already existed. @@ -706,13 +709,13 @@ SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N, SDValue Op, case ISD::DBG_LABEL: case ISD::DBG_STOPPOINT: case ISD::EH_LABEL: - return 0; // Never add these nodes. + return 0; // Never add 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 0; // Never CSE anything that produces a flag. + return 0; // Never CSE anything that produces a flag. SDValue Ops[] = { Op }; FoldingSetNodeID ID; @@ -732,7 +735,7 @@ SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N, // 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 0; // Never CSE anything that produces a flag. + return 0; // Never CSE anything that produces a flag. SDValue Ops[] = { Op1, Op2 }; FoldingSetNodeID ID; @@ -758,13 +761,13 @@ SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N, case ISD::DBG_STOPPOINT: case ISD::EH_LABEL: case ISD::DECLARE: - return 0; // Never add these nodes. + return 0; // Never add 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 0; // Never CSE anything that produces a flag. + return 0; // Never CSE anything that produces a flag. FoldingSetNodeID ID; AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops, NumOps); @@ -794,10 +797,14 @@ void SelectionDAG::VerifyNode(SDNode *N) { assert(N->getValueType(0).isVector() && "Wrong BUILD_VECTOR return type!"); assert(N->getNumOperands() == N->getValueType(0).getVectorNumElements() && "Wrong number of BUILD_VECTOR operands!"); - MVT EltVT = N->getValueType(0).getVectorElementType(); - for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) - assert(I->getSDValue().getValueType() == EltVT && - "Wrong BUILD_VECTOR operand type!"); + // FIXME: Change vector_shuffle to a variadic node with mask elements being + // operands of the node. Currently the mask is a BUILD_VECTOR passed as an + // operand, and it is not always possible to legalize it. Turning off the + // following checks at least makes it possible to legalize most of the time. +// MVT EltVT = N->getValueType(0).getVectorElementType(); +// for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) +// assert(I->getSDValue().getValueType() == EltVT && +// "Wrong BUILD_VECTOR operand type!"); break; } } @@ -836,8 +843,12 @@ void SelectionDAG::allnodes_clear() { while (!AllNodes.empty()) { SDNode *N = AllNodes.remove(AllNodes.begin()); N->SetNextInBucket(0); - if (N->OperandsNeedDelete) + + if (N->OperandsNeedDelete) { delete [] N->OperandList; + N->OperandList = 0; + } + NodeAllocator.Deallocate(N); } } @@ -962,10 +973,15 @@ SDValue SelectionDAG::getConstantFP(double Val, MVT VT, bool isTarget) { } SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV, - MVT VT, int Offset, + MVT VT, int64_t Offset, bool isTargetGA) { unsigned Opc; + // Truncate (with sign-extension) the offset value to the pointer size. + unsigned BitWidth = TLI.getPointerTy().getSizeInBits(); + if (BitWidth < 64) + Offset = (Offset << (64 - BitWidth) >> (64 - BitWidth)); + const GlobalVariable *GVar = dyn_cast(GV); if (!GVar) { // If GV is an alias then use the aliasee for determining thread-localness. @@ -2020,6 +2036,7 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{ bool SelectionDAG::isVerifiedDebugInfoDesc(SDValue Op) const { GlobalAddressSDNode *GA = dyn_cast(Op); if (!GA) return false; + if (GA->getOffset() != 0) return false; GlobalVariable *GV = dyn_cast(GA->getGlobal()); if (!GV) return false; MachineModuleInfo *MMI = getMachineModuleInfo(); @@ -2129,29 +2146,32 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, SDValue Operand) { V.clearSign(); return getConstantFP(V, VT); case ISD::FP_ROUND: - case ISD::FP_EXTEND: + case ISD::FP_EXTEND: { + bool ignored; // This can return overflow, underflow, or inexact; we don't care. // FIXME need to be more flexible about rounding mode. (void)V.convert(*MVTToAPFloatSemantics(VT), - APFloat::rmNearestTiesToEven); + APFloat::rmNearestTiesToEven, &ignored); return getConstantFP(V, VT); + } case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: { integerPart x; + bool ignored; assert(integerPartWidth >= 64); // FIXME need to be more flexible about rounding mode. APFloat::opStatus s = V.convertToInteger(&x, 64U, Opcode==ISD::FP_TO_SINT, - APFloat::rmTowardZero); + APFloat::rmTowardZero, &ignored); if (s==APFloat::opInvalidOp) // inexact is OK, in fact usual break; return getConstant(x, VT); } case ISD::BIT_CONVERT: if (VT == MVT::i32 && C->getValueType(0) == MVT::f32) - return getConstant((uint32_t)V.convertToAPInt().getZExtValue(), VT); + return getConstant((uint32_t)V.bitcastToAPInt().getZExtValue(), VT); else if (VT == MVT::i64 && C->getValueType(0) == MVT::f64) - return getConstant(V.convertToAPInt().getZExtValue(), VT); + return getConstant(V.bitcastToAPInt().getZExtValue(), VT); break; } } @@ -2325,6 +2345,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, // Fold trivial token factors. if (N1.getOpcode() == ISD::EntryToken) return N2; if (N2.getOpcode() == ISD::EntryToken) return N1; + if (N1 == N2) return N1; break; case ISD::CONCAT_VECTORS: // A CONCAT_VECTOR with all operands BUILD_VECTOR can be simplified to @@ -2931,7 +2952,7 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, // Expand memcpy to a series of load and store ops if the size operand falls // below a certain threshold. std::vector MemOps; - uint64_t Limit = -1; + uint64_t Limit = -1ULL; if (!AlwaysInline) Limit = TLI.getMaxStoresPerMemcpy(); unsigned DstAlign = Align; // Destination alignment can change. @@ -2989,7 +3010,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, // Expand memmove to a series of load and store ops if the size operand falls // below a certain threshold. std::vector MemOps; - uint64_t Limit = -1; + uint64_t Limit = -1ULL; if (!AlwaysInline) Limit = TLI.getMaxStoresPerMemmove(); unsigned DstAlign = Align; // Destination alignment can change. @@ -3195,7 +3216,7 @@ SDValue SelectionDAG::getMemset(SDValue Chain, SDValue Dst, // code. If the target chooses to do this, this is the next best. SDValue Result = TLI.EmitTargetCodeForMemset(*this, Chain, Dst, Src, Size, Align, - DstSV, DstSVOff, NoBuiltin); + DstSV, DstSVOff); if (Result.getNode()) return Result; @@ -3333,6 +3354,46 @@ SDValue SelectionDAG::getMergeValues(const SDValue *Ops, unsigned NumOps, return getNode(ISD::MERGE_VALUES, getVTList(&VTs[0], NumOps), Ops, NumOps); } +SDValue +SelectionDAG::getMemIntrinsicNode(unsigned Opcode, + const MVT *VTs, unsigned NumVTs, + const SDValue *Ops, unsigned NumOps, + MVT MemVT, const Value *srcValue, int SVOff, + unsigned Align, bool Vol, + bool ReadMem, bool WriteMem) { + return getMemIntrinsicNode(Opcode, makeVTList(VTs, NumVTs), Ops, NumOps, + MemVT, srcValue, SVOff, Align, Vol, + ReadMem, WriteMem); +} + +SDValue +SelectionDAG::getMemIntrinsicNode(unsigned Opcode, SDVTList VTList, + const SDValue *Ops, unsigned NumOps, + MVT MemVT, const Value *srcValue, int SVOff, + unsigned Align, bool Vol, + bool ReadMem, bool WriteMem) { + // Memoize the node unless it returns a flag. + MemIntrinsicSDNode *N; + if (VTList.VTs[VTList.NumVTs-1] != MVT::Flag) { + FoldingSetNodeID ID; + AddNodeIDNode(ID, Opcode, VTList, Ops, NumOps); + void *IP = 0; + if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) + return SDValue(E, 0); + + N = NodeAllocator.Allocate(); + new (N) MemIntrinsicSDNode(Opcode, VTList, Ops, NumOps, MemVT, + srcValue, SVOff, Align, Vol, ReadMem, WriteMem); + CSEMap.InsertNode(N, IP); + } else { + N = NodeAllocator.Allocate(); + new (N) MemIntrinsicSDNode(Opcode, VTList, Ops, NumOps, MemVT, + srcValue, SVOff, Align, Vol, ReadMem, WriteMem); + } + AllNodes.push_back(N); + return SDValue(N, 0); +} + SDValue SelectionDAG::getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall, bool IsInreg, SDVTList VTs, @@ -4161,6 +4222,7 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc, if (NumOps > N->NumOperands) { if (N->OperandsNeedDelete) delete[] N->OperandList; + if (N->isMachineOpcode()) { // We're creating a final node that will live unmorphed for the // remainder of the current SelectionDAG iteration, so we can allocate @@ -4677,6 +4739,7 @@ void MemSDNode::ANCHOR() {} void LoadSDNode::ANCHOR() {} void StoreSDNode::ANCHOR() {} void AtomicSDNode::ANCHOR() {} +void MemIntrinsicSDNode::ANCHOR() {} void CallSDNode::ANCHOR() {} HandleSDNode::~HandleSDNode() { @@ -4684,7 +4747,7 @@ HandleSDNode::~HandleSDNode() { } GlobalAddressSDNode::GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, - MVT VT, int o) + MVT VT, int64_t o) : SDNode(isa(GA) && cast(GA)->isThreadLocal() ? // Thread Local @@ -4706,6 +4769,17 @@ MemSDNode::MemSDNode(unsigned Opc, SDVTList VTs, MVT memvt, assert(isVolatile() == vol && "Volatile representation error!"); } +MemSDNode::MemSDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, + unsigned NumOps, MVT memvt, const Value *srcValue, + int SVO, unsigned alignment, bool vol) + : SDNode(Opc, VTs, Ops, NumOps), + MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO), + Flags(vol | ((Log2_32(alignment) + 1) << 1)) { + assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!"); + assert(getAlignment() == alignment && "Alignment representation error!"); + assert(isVolatile() == vol && "Volatile representation error!"); +} + /// getMemOperand - Return a MachineMemOperand object describing the memory /// reference performed by this memory reference. MachineMemOperand MemSDNode::getMemOperand() const { @@ -4714,10 +4788,15 @@ MachineMemOperand MemSDNode::getMemOperand() const { Flags = MachineMemOperand::MOLoad; else if (isa(this)) Flags = MachineMemOperand::MOStore; - else { - assert(isa(this) && "Unknown MemSDNode opcode!"); + else if (isa(this)) { Flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore; } + else { + const MemIntrinsicSDNode* MemIntrinNode = dyn_cast(this); + assert(MemIntrinNode && "Unknown MemSDNode opcode!"); + if (MemIntrinNode->readMem()) Flags |= MachineMemOperand::MOLoad; + if (MemIntrinNode->writeMem()) Flags |= MachineMemOperand::MOStore; + } int Size = (getMemoryVT().getSizeInBits() + 7) >> 3; if (isVolatile()) Flags |= MachineMemOperand::MOVolatile; @@ -5249,12 +5328,12 @@ void SDNode::print(raw_ostream &OS, const SelectionDAG *G) const { OS << '<' << CSDN->getValueAPF().convertToDouble() << '>'; else { OS << "getValueAPF().convertToAPInt().dump(); + CSDN->getValueAPF().bitcastToAPInt().dump(); OS << ")>"; } } else if (const GlobalAddressSDNode *GADN = dyn_cast(this)) { - int offset = GADN->getOffset(); + int64_t offset = GADN->getOffset(); OS << '<'; WriteAsOperand(OS, GADN->getGlobal()); OS << '>';