diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-01-06 21:34:26 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-01-06 21:34:26 +0000 |
commit | d215fd3b74b90f5dc1964610926fcc2a20f959aa (patch) | |
tree | 0c9f21e40eae033d6760008729f37d2103e2c654 /lib/CodeGen/SelectionDAG | |
parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) |
Notes
Diffstat (limited to 'lib/CodeGen/SelectionDAG')
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 43 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/FastISel.cpp | 12 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp | 14 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp | 58 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp | 37 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 12 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 10 |
7 files changed, 88 insertions, 98 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 3218dce8f5752..81bff4d7eefad 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3850,7 +3850,6 @@ bool DAGCombiner::SearchForAndLoads(SDNode *N, return false; } case ISD::ZERO_EXTEND: - case ISD::ANY_EXTEND: case ISD::AssertZext: { unsigned ActiveBits = Mask->getAPIntValue().countTrailingOnes(); EVT ExtVT = EVT::getIntegerVT(*DAG.getContext(), ActiveBits); @@ -13783,30 +13782,30 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { } } - // Deal with elidable overlapping chained stores. - if (StoreSDNode *ST1 = dyn_cast<StoreSDNode>(Chain)) - if (OptLevel != CodeGenOpt::None && ST->isUnindexed() && - ST1->isUnindexed() && !ST1->isVolatile() && ST1->hasOneUse() && - !ST1->getBasePtr().isUndef() && !ST->isVolatile()) { - BaseIndexOffset STBasePtr = BaseIndexOffset::match(ST->getBasePtr(), DAG); - BaseIndexOffset ST1BasePtr = - BaseIndexOffset::match(ST1->getBasePtr(), DAG); - unsigned STBytes = ST->getMemoryVT().getStoreSize(); - unsigned ST1Bytes = ST1->getMemoryVT().getStoreSize(); - int64_t PtrDiff; - // If this is a store who's preceeding store to a subset of the same - // memory and no one other node is chained to that store we can - // effectively drop the store. Do not remove stores to undef as they may - // be used as data sinks. - - if (((ST->getBasePtr() == ST1->getBasePtr()) && - (ST->getValue() == ST1->getValue())) || - (STBasePtr.equalBaseIndex(ST1BasePtr, DAG, PtrDiff) && - (0 <= PtrDiff) && (PtrDiff + ST1Bytes <= STBytes))) { + if (StoreSDNode *ST1 = dyn_cast<StoreSDNode>(Chain)) { + if (ST->isUnindexed() && !ST->isVolatile() && ST1->isUnindexed() && + !ST1->isVolatile() && ST1->getBasePtr() == Ptr && + ST->getMemoryVT() == ST1->getMemoryVT()) { + // If this is a store followed by a store with the same value to the same + // location, then the store is dead/noop. + if (ST1->getValue() == Value) { + // The store is dead, remove it. + return Chain; + } + + // If this is a store who's preceeding store to the same location + // and no one other node is chained to that store we can effectively + // drop the store. Do not remove stores to undef as they may be used as + // data sinks. + if (OptLevel != CodeGenOpt::None && ST1->hasOneUse() && + !ST1->getBasePtr().isUndef()) { + // ST1 is fully overwritten and can be elided. Combine with it's chain + // value. CombineTo(ST1, ST1->getChain()); - return SDValue(N, 0); + return SDValue(); } } + } // If this is an FP_ROUND or TRUNC followed by a store, fold this into a // truncating store. We can do this even if this is already a truncstore. diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index d3c94b5f9e6b4..3c856914053bd 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -2051,11 +2051,9 @@ bool FastISel::handlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) { // At this point we know that there is a 1-1 correspondence between LLVM PHI // nodes and Machine PHI nodes, but the incoming operands have not been // emitted yet. - for (BasicBlock::const_iterator I = SuccBB->begin(); - const auto *PN = dyn_cast<PHINode>(I); ++I) { - + for (const PHINode &PN : SuccBB->phis()) { // Ignore dead phi's. - if (PN->use_empty()) + if (PN.use_empty()) continue; // Only handle legal types. Two interesting things to note here. First, @@ -2064,7 +2062,7 @@ bool FastISel::handlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) { // own moves. Second, this check is necessary because FastISel doesn't // use CreateRegs to create registers, so it always creates // exactly one register for each non-void instruction. - EVT VT = TLI.getValueType(DL, PN->getType(), /*AllowUnknown=*/true); + EVT VT = TLI.getValueType(DL, PN.getType(), /*AllowUnknown=*/true); if (VT == MVT::Other || !TLI.isTypeLegal(VT)) { // Handle integer promotions, though, because they're common and easy. if (!(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)) { @@ -2073,11 +2071,11 @@ bool FastISel::handlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) { } } - const Value *PHIOp = PN->getIncomingValueForBlock(LLVMBB); + const Value *PHIOp = PN.getIncomingValueForBlock(LLVMBB); // Set the DebugLoc for the copy. Prefer the location of the operand // if there is one; use the location of the PHI otherwise. - DbgLoc = PN->getDebugLoc(); + DbgLoc = PN.getDebugLoc(); if (const auto *Inst = dyn_cast<Instruction>(PHIOp)) DbgLoc = Inst->getDebugLoc(); diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index c7cdb49203b15..81347fa4bd468 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -257,20 +257,20 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, // Create Machine PHI nodes for LLVM PHI nodes, lowering them as // appropriate. - for (BasicBlock::const_iterator I = BB.begin(); - const PHINode *PN = dyn_cast<PHINode>(I); ++I) { - if (PN->use_empty()) continue; + for (const PHINode &PN : BB.phis()) { + if (PN.use_empty()) + continue; // Skip empty types - if (PN->getType()->isEmptyTy()) + if (PN.getType()->isEmptyTy()) continue; - DebugLoc DL = PN->getDebugLoc(); - unsigned PHIReg = ValueMap[PN]; + DebugLoc DL = PN.getDebugLoc(); + unsigned PHIReg = ValueMap[&PN]; assert(PHIReg && "PHI node does not have an assigned virtual register!"); SmallVector<EVT, 4> ValueVTs; - ComputeValueVTs(*TLI, MF->getDataLayout(), PN->getType(), ValueVTs); + ComputeValueVTs(*TLI, MF->getDataLayout(), PN.getType(), ValueVTs); for (EVT VT : ValueVTs) { unsigned NumRegisters = TLI->getNumRegisters(Fn->getContext(), VT); const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp index 7643790df3500..6a141818bb6d8 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -139,14 +139,14 @@ class VectorLegalizer { /// \brief Implements [SU]INT_TO_FP vector promotion. /// - /// This is a [zs]ext of the input operand to the next size up. + /// This is a [zs]ext of the input operand to a larger integer type. SDValue PromoteINT_TO_FP(SDValue Op); /// \brief Implements FP_TO_[SU]INT vector promotion of the result type. /// - /// It is promoted to the next size up integer type. The result is then + /// It is promoted to a larger integer type. The result is then /// truncated back to the original type. - SDValue PromoteFP_TO_INT(SDValue Op, bool isSigned); + SDValue PromoteFP_TO_INT(SDValue Op); public: VectorLegalizer(SelectionDAG& dag) : @@ -431,7 +431,7 @@ SDValue VectorLegalizer::Promote(SDValue Op) { case ISD::FP_TO_UINT: case ISD::FP_TO_SINT: // Promote the operation by extending the operand. - return PromoteFP_TO_INT(Op, Op->getOpcode() == ISD::FP_TO_SINT); + return PromoteFP_TO_INT(Op); } // There are currently two cases of vector promotion: @@ -472,20 +472,11 @@ SDValue VectorLegalizer::Promote(SDValue Op) { SDValue VectorLegalizer::PromoteINT_TO_FP(SDValue Op) { // INT_TO_FP operations may require the input operand be promoted even // when the type is otherwise legal. - EVT VT = Op.getOperand(0).getValueType(); - assert(Op.getNode()->getNumValues() == 1 && - "Can't promote a vector with multiple results!"); - - // Normal getTypeToPromoteTo() doesn't work here, as that will promote - // by widening the vector w/ the same element width and twice the number - // of elements. We want the other way around, the same number of elements, - // each twice the width. - // - // Increase the bitwidth of the element to the next pow-of-two - // (which is greater than 8 bits). + MVT VT = Op.getOperand(0).getSimpleValueType(); + MVT NVT = TLI.getTypeToPromoteTo(Op.getOpcode(), VT); + assert(NVT.getVectorNumElements() == VT.getVectorNumElements() && + "Vectors have different number of elements!"); - EVT NVT = VT.widenIntegerVectorElementType(*DAG.getContext()); - assert(NVT.isSimple() && "Promoting to a non-simple vector type!"); SDLoc dl(Op); SmallVector<SDValue, 4> Operands(Op.getNumOperands()); @@ -505,35 +496,28 @@ SDValue VectorLegalizer::PromoteINT_TO_FP(SDValue Op) { // elements and then truncate the result. This is different from the default // PromoteVector which uses bitcast to promote thus assumning that the // promoted vector type has the same overall size. -SDValue VectorLegalizer::PromoteFP_TO_INT(SDValue Op, bool isSigned) { - assert(Op.getNode()->getNumValues() == 1 && - "Can't promote a vector with multiple results!"); - EVT VT = Op.getValueType(); +SDValue VectorLegalizer::PromoteFP_TO_INT(SDValue Op) { + MVT VT = Op.getSimpleValueType(); + MVT NVT = TLI.getTypeToPromoteTo(Op.getOpcode(), VT); + assert(NVT.getVectorNumElements() == VT.getVectorNumElements() && + "Vectors have different number of elements!"); - EVT NewVT = VT; - unsigned NewOpc; - while (true) { - NewVT = NewVT.widenIntegerVectorElementType(*DAG.getContext()); - assert(NewVT.isSimple() && "Promoting to a non-simple vector type!"); - if (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NewVT)) { - NewOpc = ISD::FP_TO_SINT; - break; - } - if (!isSigned && TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NewVT)) { - NewOpc = ISD::FP_TO_UINT; - break; - } - } + unsigned NewOpc = Op->getOpcode(); + // Change FP_TO_UINT to FP_TO_SINT if possible. + // TODO: Should we only do this if FP_TO_UINT itself isn't legal? + if (NewOpc == ISD::FP_TO_UINT && + TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT)) + NewOpc = ISD::FP_TO_SINT; SDLoc dl(Op); - SDValue Promoted = DAG.getNode(NewOpc, dl, NewVT, Op.getOperand(0)); + SDValue Promoted = DAG.getNode(NewOpc, dl, NVT, Op.getOperand(0)); // Assert that the converted value fits in the original type. If it doesn't // (eg: because the value being converted is too big), then the result of the // original operation was undefined anyway, so the assert is still correct. Promoted = DAG.getNode(Op->getOpcode() == ISD::FP_TO_UINT ? ISD::AssertZext : ISD::AssertSext, - dl, NewVT, Promoted, + dl, NVT, Promoted, DAG.getValueType(VT.getScalarType())); return DAG.getNode(ISD::TRUNCATE, dl, VT, Promoted); } diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index ce1c01b621f05..df1cbeb927409 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -3374,11 +3374,9 @@ SDValue DAGTypeLegalizer::WidenVecOp_EXTEND(SDNode *N) { EVT VT = N->getValueType(0); SDValue InOp = N->getOperand(0); - // If some legalization strategy other than widening is used on the operand, - // we can't safely assume that just extending the low lanes is the correct - // transformation. - if (getTypeAction(InOp.getValueType()) != TargetLowering::TypeWidenVector) - return WidenVecOp_Convert(N); + assert(getTypeAction(InOp.getValueType()) == + TargetLowering::TypeWidenVector && + "Unexpected type action"); InOp = GetWidenedVector(InOp); assert(VT.getVectorNumElements() < InOp.getValueType().getVectorNumElements() && @@ -3440,20 +3438,31 @@ SDValue DAGTypeLegalizer::WidenVecOp_FCOPYSIGN(SDNode *N) { } SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) { - // Since the result is legal and the input is illegal, it is unlikely that we - // can fix the input to a legal type so unroll the convert into some scalar - // code and create a nasty build vector. + // Since the result is legal and the input is illegal. EVT VT = N->getValueType(0); EVT EltVT = VT.getVectorElementType(); SDLoc dl(N); unsigned NumElts = VT.getVectorNumElements(); SDValue InOp = N->getOperand(0); - if (getTypeAction(InOp.getValueType()) == TargetLowering::TypeWidenVector) - InOp = GetWidenedVector(InOp); + assert(getTypeAction(InOp.getValueType()) == + TargetLowering::TypeWidenVector && + "Unexpected type action"); + InOp = GetWidenedVector(InOp); EVT InVT = InOp.getValueType(); + unsigned Opcode = N->getOpcode(); + + // See if a widened result type would be legal, if so widen the node. + EVT WideVT = EVT::getVectorVT(*DAG.getContext(), EltVT, + InVT.getVectorNumElements()); + if (TLI.isTypeLegal(WideVT)) { + SDValue Res = DAG.getNode(Opcode, dl, WideVT, InOp); + return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, Res, + DAG.getIntPtrConstant(0, dl)); + } + EVT InEltVT = InVT.getVectorElementType(); - unsigned Opcode = N->getOpcode(); + // Unroll the convert into some scalar code and create a nasty build vector. SmallVector<SDValue, 16> Ops(NumElts); for (unsigned i=0; i < NumElts; ++i) Ops[i] = DAG.getNode( @@ -3506,8 +3515,10 @@ SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) { unsigned NumOperands = N->getNumOperands(); for (unsigned i=0; i < NumOperands; ++i) { SDValue InOp = N->getOperand(i); - if (getTypeAction(InOp.getValueType()) == TargetLowering::TypeWidenVector) - InOp = GetWidenedVector(InOp); + assert(getTypeAction(InOp.getValueType()) == + TargetLowering::TypeWidenVector && + "Unexpected type action"); + InOp = GetWidenedVector(InOp); for (unsigned j=0; j < NumInElts; ++j) Ops[Idx++] = DAG.getNode( ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 71cb8cb78f6d3..68bbd62e1321e 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -8940,17 +8940,17 @@ SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) { // At this point we know that there is a 1-1 correspondence between LLVM PHI // nodes and Machine PHI nodes, but the incoming operands have not been // emitted yet. - for (BasicBlock::const_iterator I = SuccBB->begin(); - const PHINode *PN = dyn_cast<PHINode>(I); ++I) { + for (const PHINode &PN : SuccBB->phis()) { // Ignore dead phi's. - if (PN->use_empty()) continue; + if (PN.use_empty()) + continue; // Skip empty types - if (PN->getType()->isEmptyTy()) + if (PN.getType()->isEmptyTy()) continue; unsigned Reg; - const Value *PHIOp = PN->getIncomingValueForBlock(LLVMBB); + const Value *PHIOp = PN.getIncomingValueForBlock(LLVMBB); if (const Constant *C = dyn_cast<Constant>(PHIOp)) { unsigned &RegOut = ConstantsOut[C]; @@ -8977,7 +8977,7 @@ SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) { // the input for this MBB. SmallVector<EVT, 4> ValueVTs; const TargetLowering &TLI = DAG.getTargetLoweringInfo(); - ComputeValueVTs(TLI, DAG.getDataLayout(), PN->getType(), ValueVTs); + ComputeValueVTs(TLI, DAG.getDataLayout(), PN.getType(), ValueVTs); for (unsigned vti = 0, vte = ValueVTs.size(); vti != vte; ++vti) { EVT VT = ValueVTs[vti]; unsigned NumRegisters = TLI.getNumRegisters(*DAG.getContext(), VT); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index d13ccc2637183..befd797e75b42 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1445,13 +1445,11 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { } if (AllPredsVisited) { - for (BasicBlock::const_iterator I = LLVMBB->begin(); - const PHINode *PN = dyn_cast<PHINode>(I); ++I) - FuncInfo->ComputePHILiveOutRegInfo(PN); + for (const PHINode &PN : LLVMBB->phis()) + FuncInfo->ComputePHILiveOutRegInfo(&PN); } else { - for (BasicBlock::const_iterator I = LLVMBB->begin(); - const PHINode *PN = dyn_cast<PHINode>(I); ++I) - FuncInfo->InvalidatePHILiveOutRegInfo(PN); + for (const PHINode &PN : LLVMBB->phis()) + FuncInfo->InvalidatePHILiveOutRegInfo(&PN); } FuncInfo->VisitedBBs.insert(LLVMBB); |