diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-02-16 09:30:23 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-02-16 09:30:23 +0000 |
commit | 6fe5c7aa327e188b7176daa5595bbf075a6b94df (patch) | |
tree | 4cfca640904d1896e25032757a61f8959c066919 /lib/CodeGen/SelectionDAG | |
parent | 989df958a10f0beb90b89ccadd8351cbe51d90b1 (diff) |
Notes
Diffstat (limited to 'lib/CodeGen/SelectionDAG')
18 files changed, 1241 insertions, 1253 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 8883064df999c..7da7848930f13 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1881,7 +1881,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) { LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), MemVT, - LN0->isVolatile(), LN0->getAlignment()); + LN0->isVolatile(), LN0->isNonTemporal(), + LN0->getAlignment()); AddToWorkList(N); CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! @@ -1903,7 +1904,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) { LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), MemVT, - LN0->isVolatile(), LN0->getAlignment()); + LN0->isVolatile(), LN0->isNonTemporal(), + LN0->getAlignment()); AddToWorkList(N); CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! @@ -1935,7 +1937,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) { DAG.getExtLoad(ISD::ZEXTLOAD, LN0->getDebugLoc(), LoadResultTy, LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), - ExtVT, LN0->isVolatile(), LN0->getAlignment()); + ExtVT, LN0->isVolatile(), LN0->isNonTemporal(), + LN0->getAlignment()); AddToWorkList(N); CombineTo(LN0, NewLoad, NewLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! @@ -1970,7 +1973,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) { DAG.getExtLoad(ISD::ZEXTLOAD, LN0->getDebugLoc(), LoadResultTy, LN0->getChain(), NewPtr, LN0->getSrcValue(), LN0->getSrcValueOffset(), - ExtVT, LN0->isVolatile(), Alignment); + ExtVT, LN0->isVolatile(), LN0->isNonTemporal(), + Alignment); AddToWorkList(N); CombineTo(LN0, Load, Load.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! @@ -2640,7 +2644,7 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { // If the shift is not a no-op (in which case this should be just a sign // extend already), the truncated to type is legal, sign_extend is legal - // on that type, and the the truncate to that type is both legal and free, + // on that type, and the truncate to that type is both legal and free, // perform the transform. if ((ShiftAmt > 0) && TLI.isOperationLegalOrCustom(ISD::SIGN_EXTEND, TruncVT) && @@ -3143,7 +3147,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), N0.getValueType(), - LN0->isVolatile(), LN0->getAlignment()); + LN0->isVolatile(), LN0->isNonTemporal(), + LN0->getAlignment()); CombineTo(N, ExtLoad); SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), N0.getValueType(), ExtLoad); @@ -3185,7 +3190,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), MemVT, - LN0->isVolatile(), LN0->getAlignment()); + LN0->isVolatile(), LN0->isNonTemporal(), + LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), @@ -3220,6 +3226,14 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { NegOne, DAG.getConstant(0, VT), cast<CondCodeSDNode>(N0.getOperand(2))->get(), true); if (SCC.getNode()) return SCC; + if (!LegalOperations || + TLI.isOperationLegal(ISD::SETCC, TLI.getSetCCResultType(VT))) + return DAG.getNode(ISD::SELECT, N->getDebugLoc(), VT, + DAG.getSetCC(N->getDebugLoc(), + TLI.getSetCCResultType(VT), + N0.getOperand(0), N0.getOperand(1), + cast<CondCodeSDNode>(N0.getOperand(2))->get()), + NegOne, DAG.getConstant(0, VT)); } @@ -3307,7 +3321,8 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), N0.getValueType(), - LN0->isVolatile(), LN0->getAlignment()); + LN0->isVolatile(), LN0->isNonTemporal(), + LN0->getAlignment()); CombineTo(N, ExtLoad); SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), N0.getValueType(), ExtLoad); @@ -3349,7 +3364,8 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), MemVT, - LN0->isVolatile(), LN0->getAlignment()); + LN0->isVolatile(), LN0->isNonTemporal(), + LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), N0.getValueType(), @@ -3463,7 +3479,8 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), N0.getValueType(), - LN0->isVolatile(), LN0->getAlignment()); + LN0->isVolatile(), LN0->isNonTemporal(), + LN0->getAlignment()); CombineTo(N, ExtLoad); SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), N0.getValueType(), ExtLoad); @@ -3505,7 +3522,8 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { VT, LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), MemVT, - LN0->isVolatile(), LN0->getAlignment()); + LN0->isVolatile(), LN0->isNonTemporal(), + LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), @@ -3628,10 +3646,11 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) { SDValue Load = (ExtType == ISD::NON_EXTLOAD) ? DAG.getLoad(VT, N0.getDebugLoc(), LN0->getChain(), NewPtr, LN0->getSrcValue(), LN0->getSrcValueOffset() + PtrOff, - LN0->isVolatile(), NewAlign) + LN0->isVolatile(), LN0->isNonTemporal(), NewAlign) : DAG.getExtLoad(ExtType, N0.getDebugLoc(), VT, LN0->getChain(), NewPtr, LN0->getSrcValue(), LN0->getSrcValueOffset() + PtrOff, - ExtVT, LN0->isVolatile(), NewAlign); + ExtVT, LN0->isVolatile(), LN0->isNonTemporal(), + NewAlign); // Replace the old load's chain with the new load's chain. WorkListRemover DeadNodes(*this); @@ -3718,7 +3737,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT, - LN0->isVolatile(), LN0->getAlignment()); + LN0->isVolatile(), LN0->isNonTemporal(), + LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! @@ -3734,7 +3754,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT, - LN0->isVolatile(), LN0->getAlignment()); + LN0->isVolatile(), LN0->isNonTemporal(), + LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! @@ -3818,7 +3839,7 @@ SDValue DAGCombiner::CombineConsecutiveLoads(SDNode *N, EVT VT) { (!LegalOperations || TLI.isOperationLegal(ISD::LOAD, VT))) return DAG.getLoad(VT, N->getDebugLoc(), LD1->getChain(), LD1->getBasePtr(), LD1->getSrcValue(), - LD1->getSrcValueOffset(), false, Align); + LD1->getSrcValueOffset(), false, false, Align); } return SDValue(); @@ -3888,7 +3909,8 @@ SDValue DAGCombiner::visitBIT_CONVERT(SDNode *N) { SDValue Load = DAG.getLoad(VT, N->getDebugLoc(), LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), - LN0->isVolatile(), OrigAlign); + LN0->isVolatile(), LN0->isNonTemporal(), + OrigAlign); AddToWorkList(N); CombineTo(N0.getNode(), DAG.getNode(ISD::BIT_CONVERT, N0.getDebugLoc(), @@ -4484,7 +4506,8 @@ SDValue DAGCombiner::visitFP_EXTEND(SDNode *N) { LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), N0.getValueType(), - LN0->isVolatile(), LN0->getAlignment()); + LN0->isVolatile(), LN0->isNonTemporal(), + LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), DAG.getNode(ISD::FP_ROUND, N0.getDebugLoc(), @@ -4952,7 +4975,7 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) { LD->getValueType(0), Chain, Ptr, LD->getSrcValue(), LD->getSrcValueOffset(), LD->getMemoryVT(), - LD->isVolatile(), Align); + LD->isVolatile(), LD->isNonTemporal(), Align); } } @@ -5034,7 +5057,8 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) { ReplLoad = DAG.getLoad(N->getValueType(0), LD->getDebugLoc(), BetterChain, Ptr, LD->getSrcValue(), LD->getSrcValueOffset(), - LD->isVolatile(), LD->getAlignment()); + LD->isVolatile(), LD->isNonTemporal(), + LD->getAlignment()); } else { ReplLoad = DAG.getExtLoad(LD->getExtensionType(), LD->getDebugLoc(), LD->getValueType(0), @@ -5042,6 +5066,7 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) { LD->getSrcValueOffset(), LD->getMemoryVT(), LD->isVolatile(), + LD->isNonTemporal(), LD->getAlignment()); } @@ -5141,13 +5166,14 @@ SDValue DAGCombiner::ReduceLoadOpStoreWidth(SDNode *N) { SDValue NewLD = DAG.getLoad(NewVT, N0.getDebugLoc(), LD->getChain(), NewPtr, LD->getSrcValue(), LD->getSrcValueOffset(), - LD->isVolatile(), NewAlign); + LD->isVolatile(), LD->isNonTemporal(), + NewAlign); SDValue NewVal = DAG.getNode(Opc, Value.getDebugLoc(), NewVT, NewLD, DAG.getConstant(NewImm, NewVT)); SDValue NewST = DAG.getStore(Chain, N->getDebugLoc(), NewVal, NewPtr, ST->getSrcValue(), ST->getSrcValueOffset(), - false, NewAlign); + false, false, NewAlign); AddToWorkList(NewPtr.getNode()); AddToWorkList(NewLD.getNode()); @@ -5176,7 +5202,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { return DAG.getTruncStore(Chain, N->getDebugLoc(), Value, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->getMemoryVT(), - ST->isVolatile(), Align); + ST->isVolatile(), ST->isNonTemporal(), Align); } } @@ -5193,7 +5219,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { TLI.isOperationLegalOrCustom(ISD::STORE, SVT))) return DAG.getStore(Chain, N->getDebugLoc(), Value.getOperand(0), Ptr, ST->getSrcValue(), - ST->getSrcValueOffset(), ST->isVolatile(), OrigAlign); + ST->getSrcValueOffset(), ST->isVolatile(), + ST->isNonTemporal(), OrigAlign); } // Turn 'store float 1.0, Ptr' -> 'store int 0x12345678, Ptr' @@ -5219,7 +5246,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { return DAG.getStore(Chain, N->getDebugLoc(), Tmp, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), - ST->getAlignment()); + ST->isNonTemporal(), ST->getAlignment()); } break; case MVT::f64: @@ -5231,7 +5258,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { return DAG.getStore(Chain, N->getDebugLoc(), Tmp, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), - ST->getAlignment()); + ST->isNonTemporal(), ST->getAlignment()); } else if (!ST->isVolatile() && TLI.isOperationLegalOrCustom(ISD::STORE, MVT::i32)) { // Many FP stores are not made apparent until after legalize, e.g. for @@ -5245,18 +5272,21 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { int SVOffset = ST->getSrcValueOffset(); unsigned Alignment = ST->getAlignment(); bool isVolatile = ST->isVolatile(); + bool isNonTemporal = ST->isNonTemporal(); SDValue St0 = DAG.getStore(Chain, ST->getDebugLoc(), Lo, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), - isVolatile, ST->getAlignment()); + isVolatile, isNonTemporal, + ST->getAlignment()); Ptr = DAG.getNode(ISD::ADD, N->getDebugLoc(), Ptr.getValueType(), Ptr, DAG.getConstant(4, Ptr.getValueType())); SVOffset += 4; Alignment = MinAlign(Alignment, 4U); SDValue St1 = DAG.getStore(Chain, ST->getDebugLoc(), Hi, Ptr, ST->getSrcValue(), - SVOffset, isVolatile, Alignment); + SVOffset, isVolatile, isNonTemporal, + Alignment); return DAG.getNode(ISD::TokenFactor, N->getDebugLoc(), MVT::Other, St0, St1); } @@ -5278,12 +5308,13 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { if (ST->isTruncatingStore()) { ReplStore = DAG.getTruncStore(BetterChain, N->getDebugLoc(), Value, Ptr, ST->getSrcValue(),ST->getSrcValueOffset(), - ST->getMemoryVT(), - ST->isVolatile(), ST->getAlignment()); + ST->getMemoryVT(), ST->isVolatile(), + ST->isNonTemporal(), ST->getAlignment()); } else { ReplStore = DAG.getStore(BetterChain, N->getDebugLoc(), Value, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), - ST->isVolatile(), ST->getAlignment()); + ST->isVolatile(), ST->isNonTemporal(), + ST->getAlignment()); } // Create token to keep both nodes around. @@ -5317,7 +5348,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { return DAG.getTruncStore(Chain, N->getDebugLoc(), Shorter, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->getMemoryVT(), - ST->isVolatile(), ST->getAlignment()); + ST->isVolatile(), ST->isNonTemporal(), + ST->getAlignment()); // Otherwise, see if we can simplify the operation with // SimplifyDemandedBits, which only works if the value has a single use. @@ -5350,7 +5382,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { return DAG.getTruncStore(Chain, N->getDebugLoc(), Value.getOperand(0), Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->getMemoryVT(), - ST->isVolatile(), ST->getAlignment()); + ST->isVolatile(), ST->isNonTemporal(), + ST->getAlignment()); } return ReduceLoadOpStoreWidth(N); @@ -5395,12 +5428,16 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) { SDValue InVec = N->getOperand(0); if (InVec.getOpcode() == ISD::SCALAR_TO_VECTOR) { - // If the operand is wider than the vector element type then it is implicitly - // truncated. Make that explicit here. + // Check if the result type doesn't match the inserted element type. A + // SCALAR_TO_VECTOR may truncate the inserted element and the + // EXTRACT_VECTOR_ELT may widen the extracted vector. EVT EltVT = InVec.getValueType().getVectorElementType(); SDValue InOp = InVec.getOperand(0); - if (InOp.getValueType() != EltVT) - return DAG.getNode(ISD::TRUNCATE, InVec.getDebugLoc(), EltVT, InOp); + EVT NVT = N->getValueType(0); + if (InOp.getValueType() != NVT) { + assert(InOp.getValueType().isInteger() && NVT.isInteger()); + return DAG.getSExtOrTrunc(InOp, InVec.getDebugLoc(), NVT); + } return InOp; } @@ -5491,7 +5528,7 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) { return DAG.getLoad(LVT, N->getDebugLoc(), LN0->getChain(), NewPtr, LN0->getSrcValue(), LN0->getSrcValueOffset(), - LN0->isVolatile(), Align); + LN0->isVolatile(), LN0->isNonTemporal(), Align); } return SDValue(); @@ -5871,6 +5908,7 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS, LLD->getChain(), Addr, 0, 0, LLD->isVolatile(), + LLD->isNonTemporal(), LLD->getAlignment()); } else { Load = DAG.getExtLoad(LLD->getExtensionType(), @@ -5879,6 +5917,7 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS, LLD->getChain(), Addr, 0, 0, LLD->getMemoryVT(), LLD->isVolatile(), + LLD->isNonTemporal(), LLD->getAlignment()); } @@ -5986,7 +6025,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, CstOffset); return DAG.getLoad(TV->getValueType(0), DL, DAG.getEntryNode(), CPIdx, PseudoSourceValue::getConstantPool(), 0, false, - Alignment); + false, Alignment); } } diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index 09fd657fffd04..35ef5b7053432 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -121,7 +121,7 @@ unsigned FastISel::getRegForValue(Value *V) { Reg = LocalValueMap[CE]; } else if (isa<UndefValue>(V)) { Reg = createResultReg(TLI.getRegClassFor(VT)); - BuildMI(MBB, DL, TII.get(TargetInstrInfo::IMPLICIT_DEF), Reg); + BuildMI(MBB, DL, TII.get(TargetOpcode::IMPLICIT_DEF), Reg); } // If target-independent code couldn't handle the value, give target-specific @@ -332,6 +332,8 @@ bool FastISel::SelectCall(User *I) { return true; Value *Address = DI->getAddress(); + if (!Address) + return true; AllocaInst *AI = dyn_cast<AllocaInst>(Address); // Don't handle byval struct arguments or VLAs, for example. if (!AI) break; @@ -343,6 +345,9 @@ bool FastISel::SelectCall(User *I) { if (MDNode *Dbg = DI->getMetadata("dbg")) MMI->setVariableDbgInfo(DI->getVariable(), FI, Dbg); } + // Building the map above is target independent. Generating DBG_VALUE + // inline is target dependent; do this now. + (void)TargetSelectInstruction(cast<Instruction>(I)); return true; } case Intrinsic::eh_exception: { @@ -966,7 +971,7 @@ unsigned FastISel::FastEmitInst_extractsubreg(MVT RetVT, const TargetRegisterClass* RC = MRI.getRegClass(Op0); unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT)); - const TargetInstrDesc &II = TII.get(TargetInstrInfo::EXTRACT_SUBREG); + const TargetInstrDesc &II = TII.get(TargetOpcode::EXTRACT_SUBREG); if (II.getNumDefs() >= 1) BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addImm(Idx); diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index dc7d82d192d4d..50f4c325a161a 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -227,7 +227,7 @@ void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf, unsigned NumRegisters = TLI.getNumRegisters(Fn->getContext(), VT); const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); for (unsigned i = 0; i != NumRegisters; ++i) - BuildMI(MBB, DL, TII->get(TargetInstrInfo::PHI), PHIReg + i); + BuildMI(MBB, DL, TII->get(TargetOpcode::PHI), PHIReg + i); PHIReg += NumRegisters; } } diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index 9c50936056791..02fe85dd996f0 100644 --- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -178,7 +178,7 @@ void InstrEmitter::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, const TargetInstrDesc &II, bool IsClone, bool IsCloned, DenseMap<SDValue, unsigned> &VRBaseMap) { - assert(Node->getMachineOpcode() != TargetInstrInfo::IMPLICIT_DEF && + assert(Node->getMachineOpcode() != TargetOpcode::IMPLICIT_DEF && "IMPLICIT_DEF should have been handled as a special case elsewhere!"); for (unsigned i = 0; i < II.getNumDefs(); ++i) { @@ -236,7 +236,7 @@ void InstrEmitter::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, unsigned InstrEmitter::getVR(SDValue Op, DenseMap<SDValue, unsigned> &VRBaseMap) { if (Op.isMachineOpcode() && - Op.getMachineOpcode() == TargetInstrInfo::IMPLICIT_DEF) { + Op.getMachineOpcode() == TargetOpcode::IMPLICIT_DEF) { // Add an IMPLICIT_DEF instruction before every use. unsigned VReg = getDstOfOnlyCopyToRegUse(Op.getNode(), Op.getResNo()); // IMPLICIT_DEF can produce any type of result so its TargetInstrDesc @@ -246,7 +246,7 @@ unsigned InstrEmitter::getVR(SDValue Op, VReg = MRI->createVirtualRegister(RC); } BuildMI(MBB, Op.getDebugLoc(), - TII->get(TargetInstrInfo::IMPLICIT_DEF), VReg); + TII->get(TargetOpcode::IMPLICIT_DEF), VReg); return VReg; } @@ -396,12 +396,12 @@ void InstrEmitter::EmitSubregNode(SDNode *Node, } } - if (Opc == TargetInstrInfo::EXTRACT_SUBREG) { + if (Opc == TargetOpcode::EXTRACT_SUBREG) { unsigned SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue(); // Create the extract_subreg machine instruction. MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(), - TII->get(TargetInstrInfo::EXTRACT_SUBREG)); + TII->get(TargetOpcode::EXTRACT_SUBREG)); // Figure out the register class to create for the destreg. unsigned VReg = getVR(Node->getOperand(0), VRBaseMap); @@ -424,8 +424,8 @@ void InstrEmitter::EmitSubregNode(SDNode *Node, AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap); MI->addOperand(MachineOperand::CreateImm(SubIdx)); MBB->insert(InsertPos, MI); - } else if (Opc == TargetInstrInfo::INSERT_SUBREG || - Opc == TargetInstrInfo::SUBREG_TO_REG) { + } else if (Opc == TargetOpcode::INSERT_SUBREG || + Opc == TargetOpcode::SUBREG_TO_REG) { SDValue N0 = Node->getOperand(0); SDValue N1 = Node->getOperand(1); SDValue N2 = Node->getOperand(2); @@ -452,7 +452,7 @@ void InstrEmitter::EmitSubregNode(SDNode *Node, // If creating a subreg_to_reg, then the first input operand // is an implicit value immediate, otherwise it's a register - if (Opc == TargetInstrInfo::SUBREG_TO_REG) { + if (Opc == TargetOpcode::SUBREG_TO_REG) { const ConstantSDNode *SD = cast<ConstantSDNode>(N0); MI->addOperand(MachineOperand::CreateImm(SD->getZExtValue())); } else @@ -507,20 +507,20 @@ void InstrEmitter::EmitNode(SDNode *Node, bool IsClone, bool IsCloned, unsigned Opc = Node->getMachineOpcode(); // Handle subreg insert/extract specially - if (Opc == TargetInstrInfo::EXTRACT_SUBREG || - Opc == TargetInstrInfo::INSERT_SUBREG || - Opc == TargetInstrInfo::SUBREG_TO_REG) { + if (Opc == TargetOpcode::EXTRACT_SUBREG || + Opc == TargetOpcode::INSERT_SUBREG || + Opc == TargetOpcode::SUBREG_TO_REG) { EmitSubregNode(Node, VRBaseMap); return; } // Handle COPY_TO_REGCLASS specially. - if (Opc == TargetInstrInfo::COPY_TO_REGCLASS) { + if (Opc == TargetOpcode::COPY_TO_REGCLASS) { EmitCopyToRegClassNode(Node, VRBaseMap); return; } - if (Opc == TargetInstrInfo::IMPLICIT_DEF) + if (Opc == TargetOpcode::IMPLICIT_DEF) // We want a unique VR for each IMPLICIT_DEF use. return; @@ -640,7 +640,7 @@ void InstrEmitter::EmitNode(SDNode *Node, bool IsClone, bool IsCloned, // Create the inline asm machine instruction. MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(), - TII->get(TargetInstrInfo::INLINEASM)); + TII->get(TargetOpcode::INLINEASM)); // Add the asm string as an external symbol operand. const char *AsmStr = diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 5e3f58a8af41b..e9321dad8cbf2 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -377,9 +377,10 @@ static SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP, return DAG.getExtLoad(ISD::EXTLOAD, dl, OrigVT, DAG.getEntryNode(), CPIdx, PseudoSourceValue::getConstantPool(), - 0, VT, false, Alignment); + 0, VT, false, false, Alignment); return DAG.getLoad(OrigVT, dl, DAG.getEntryNode(), CPIdx, - PseudoSourceValue::getConstantPool(), 0, false, Alignment); + PseudoSourceValue::getConstantPool(), 0, false, false, + Alignment); } /// ExpandUnalignedStore - Expands an unaligned store to 2 half-size stores. @@ -402,7 +403,8 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, // FIXME: Does not handle truncating floating point stores! SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, intVT, Val); return DAG.getStore(Chain, dl, Result, Ptr, ST->getSrcValue(), - SVOffset, ST->isVolatile(), Alignment); + SVOffset, ST->isVolatile(), ST->isNonTemporal(), + Alignment); } else { // Do a (aligned) store to a stack slot, then copy from the stack slot // to the final destination using (unaligned) integer loads and stores. @@ -418,7 +420,8 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, // Perform the original store, only redirected to the stack slot. SDValue Store = DAG.getTruncStore(Chain, dl, - Val, StackPtr, NULL, 0, StoredVT); + Val, StackPtr, NULL, 0, StoredVT, + false, false, 0); SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy()); SmallVector<SDValue, 8> Stores; unsigned Offset = 0; @@ -426,11 +429,12 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, // Do all but one copies using the full register width. for (unsigned i = 1; i < NumRegs; i++) { // Load one integer register's worth from the stack slot. - SDValue Load = DAG.getLoad(RegVT, dl, Store, StackPtr, NULL, 0); + SDValue Load = DAG.getLoad(RegVT, dl, Store, StackPtr, NULL, 0, + false, false, 0); // Store it to the final location. Remember the store. Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, Ptr, ST->getSrcValue(), SVOffset + Offset, - ST->isVolatile(), + ST->isVolatile(), ST->isNonTemporal(), MinAlign(ST->getAlignment(), Offset))); // Increment the pointers. Offset += RegBytes; @@ -446,11 +450,12 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, // Load from the stack slot. SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Store, StackPtr, - NULL, 0, MemVT); + NULL, 0, MemVT, false, false, 0); Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, Ptr, ST->getSrcValue(), SVOffset + Offset, MemVT, ST->isVolatile(), + ST->isNonTemporal(), MinAlign(ST->getAlignment(), Offset))); // The order of the stores doesn't matter - say it with a TokenFactor. return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], @@ -474,13 +479,14 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, SDValue Store1, Store2; Store1 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Lo:Hi, Ptr, ST->getSrcValue(), SVOffset, NewStoredVT, - ST->isVolatile(), Alignment); + ST->isVolatile(), ST->isNonTemporal(), Alignment); Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getConstant(IncrementSize, TLI.getPointerTy())); Alignment = MinAlign(Alignment, IncrementSize); Store2 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Hi:Lo, Ptr, ST->getSrcValue(), SVOffset + IncrementSize, - NewStoredVT, ST->isVolatile(), Alignment); + NewStoredVT, ST->isVolatile(), ST->isNonTemporal(), + Alignment); return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2); } @@ -502,7 +508,7 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, // then bitconvert to floating point or vector. SDValue newLoad = DAG.getLoad(intVT, dl, Chain, Ptr, LD->getSrcValue(), SVOffset, LD->isVolatile(), - LD->getAlignment()); + LD->isNonTemporal(), LD->getAlignment()); SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, LoadedVT, newLoad); if (VT.isFloatingPoint() && LoadedVT != VT) Result = DAG.getNode(ISD::FP_EXTEND, dl, VT, Result); @@ -530,10 +536,11 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, // Load one integer register's worth from the original location. SDValue Load = DAG.getLoad(RegVT, dl, Chain, Ptr, LD->getSrcValue(), SVOffset + Offset, LD->isVolatile(), + LD->isNonTemporal(), MinAlign(LD->getAlignment(), Offset)); // Follow the load with a store to the stack slot. Remember the store. Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, StackPtr, - NULL, 0)); + NULL, 0, false, false, 0)); // Increment the pointers. Offset += RegBytes; Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment); @@ -546,12 +553,13 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Chain, Ptr, LD->getSrcValue(), SVOffset + Offset, MemVT, LD->isVolatile(), + LD->isNonTemporal(), MinAlign(LD->getAlignment(), Offset)); // Follow the load with a store to the stack slot. Remember the store. // On big-endian machines this requires a truncating store to ensure // that the bits end up in the right place. Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, StackPtr, - NULL, 0, MemVT)); + NULL, 0, MemVT, false, false, 0)); // The order of the stores doesn't matter - say it with a TokenFactor. SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], @@ -559,7 +567,7 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, // Finally, perform the original load only redirected to the stack slot. Load = DAG.getExtLoad(LD->getExtensionType(), dl, VT, TF, StackBase, - NULL, 0, LoadedVT); + NULL, 0, LoadedVT, false, false, 0); // Callers expect a MERGE_VALUES node. SDValue Ops[] = { Load, TF }; @@ -588,20 +596,22 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, SDValue Lo, Hi; if (TLI.isLittleEndian()) { Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getSrcValue(), - SVOffset, NewLoadedVT, LD->isVolatile(), Alignment); + SVOffset, NewLoadedVT, LD->isVolatile(), + LD->isNonTemporal(), Alignment); Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getConstant(IncrementSize, TLI.getPointerTy())); Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getSrcValue(), SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(), - MinAlign(Alignment, IncrementSize)); + LD->isNonTemporal(), MinAlign(Alignment, IncrementSize)); } else { Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getSrcValue(), - SVOffset, NewLoadedVT, LD->isVolatile(), Alignment); + SVOffset, NewLoadedVT, LD->isVolatile(), + LD->isNonTemporal(), Alignment); Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getConstant(IncrementSize, TLI.getPointerTy())); Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getSrcValue(), SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(), - MinAlign(Alignment, IncrementSize)); + LD->isNonTemporal(), MinAlign(Alignment, IncrementSize)); } // aggregate the two parts @@ -643,7 +653,8 @@ PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx, // Store the vector. SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Tmp1, StackPtr, - PseudoSourceValue::getFixedStack(SPFI), 0); + PseudoSourceValue::getFixedStack(SPFI), 0, + false, false, 0); // Truncate or zero extend offset to target pointer type. unsigned CastOpc = IdxVT.bitsGT(PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND; @@ -654,10 +665,12 @@ PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx, SDValue StackPtr2 = DAG.getNode(ISD::ADD, dl, IdxVT, Tmp3, StackPtr); // Store the scalar value. Ch = DAG.getTruncStore(Ch, dl, Tmp2, StackPtr2, - PseudoSourceValue::getFixedStack(SPFI), 0, EltVT); + PseudoSourceValue::getFixedStack(SPFI), 0, EltVT, + false, false, 0); // Load the updated vector. return DAG.getLoad(VT, dl, Ch, StackPtr, - PseudoSourceValue::getFixedStack(SPFI), 0); + PseudoSourceValue::getFixedStack(SPFI), 0, + false, false, 0); } @@ -702,6 +715,7 @@ SDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) { int SVOffset = ST->getSrcValueOffset(); unsigned Alignment = ST->getAlignment(); bool isVolatile = ST->isVolatile(); + bool isNonTemporal = ST->isNonTemporal(); DebugLoc dl = ST->getDebugLoc(); if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(ST->getValue())) { if (CFP->getValueType(0) == MVT::f32 && @@ -710,14 +724,14 @@ SDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) { bitcastToAPInt().zextOrTrunc(32), MVT::i32); return DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), - SVOffset, isVolatile, Alignment); + SVOffset, isVolatile, isNonTemporal, Alignment); } else if (CFP->getValueType(0) == MVT::f64) { // If this target supports 64-bit registers, do a single 64-bit store. if (getTypeAction(MVT::i64) == Legal) { Tmp3 = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt(). zextOrTrunc(64), MVT::i64); return DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), - SVOffset, isVolatile, Alignment); + SVOffset, isVolatile, isNonTemporal, Alignment); } else if (getTypeAction(MVT::i32) == Legal && !ST->isVolatile()) { // Otherwise, if the target supports 32-bit registers, use 2 32-bit // stores. If the target supports neither 32- nor 64-bits, this @@ -728,11 +742,11 @@ SDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) { if (TLI.isBigEndian()) std::swap(Lo, Hi); Lo = DAG.getStore(Tmp1, dl, Lo, Tmp2, ST->getSrcValue(), - SVOffset, isVolatile, Alignment); + SVOffset, isVolatile, isNonTemporal, Alignment); Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, DAG.getIntPtrConstant(4)); Hi = DAG.getStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(), SVOffset+4, - isVolatile, MinAlign(Alignment, 4U)); + isVolatile, isNonTemporal, MinAlign(Alignment, 4U)); return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); } @@ -1108,7 +1122,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Tmp1 = DAG.getLoad(NVT, dl, Tmp1, Tmp2, LD->getSrcValue(), LD->getSrcValueOffset(), - LD->isVolatile(), LD->getAlignment()); + LD->isVolatile(), LD->isNonTemporal(), + LD->getAlignment()); Tmp3 = LegalizeOp(DAG.getNode(ISD::BIT_CONVERT, dl, VT, Tmp1)); Tmp4 = LegalizeOp(Tmp1.getValue(1)); break; @@ -1125,6 +1140,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { int SVOffset = LD->getSrcValueOffset(); unsigned Alignment = LD->getAlignment(); bool isVolatile = LD->isVolatile(); + bool isNonTemporal = LD->isNonTemporal(); if (SrcWidth != SrcVT.getStoreSizeInBits() && // Some targets pretend to have an i1 loading operation, and actually @@ -1150,7 +1166,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Result = DAG.getExtLoad(NewExtType, dl, Node->getValueType(0), Tmp1, Tmp2, LD->getSrcValue(), SVOffset, - NVT, isVolatile, Alignment); + NVT, isVolatile, isNonTemporal, Alignment); Ch = Result.getValue(1); // The chain. @@ -1187,7 +1203,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, Node->getValueType(0), Tmp1, Tmp2, LD->getSrcValue(), SVOffset, RoundVT, isVolatile, - Alignment); + isNonTemporal, Alignment); // Load the remaining ExtraWidth bits. IncrementSize = RoundWidth / 8; @@ -1195,7 +1211,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { DAG.getIntPtrConstant(IncrementSize)); Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2, LD->getSrcValue(), SVOffset + IncrementSize, - ExtraVT, isVolatile, + ExtraVT, isVolatile, isNonTemporal, MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the @@ -1215,7 +1231,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Load the top RoundWidth bits. Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2, LD->getSrcValue(), SVOffset, RoundVT, isVolatile, - Alignment); + isNonTemporal, Alignment); // Load the remaining ExtraWidth bits. IncrementSize = RoundWidth / 8; @@ -1224,7 +1240,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, Node->getValueType(0), Tmp1, Tmp2, LD->getSrcValue(), SVOffset + IncrementSize, - ExtraVT, isVolatile, + ExtraVT, isVolatile, isNonTemporal, MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the @@ -1284,7 +1300,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { (SrcVT == MVT::f64 && Node->getValueType(0) == MVT::f128)) { SDValue Load = DAG.getLoad(SrcVT, dl, Tmp1, Tmp2, LD->getSrcValue(), LD->getSrcValueOffset(), - LD->isVolatile(), LD->getAlignment()); + LD->isVolatile(), LD->isNonTemporal(), + LD->getAlignment()); Result = DAG.getNode(ISD::FP_EXTEND, dl, Node->getValueType(0), Load); Tmp1 = LegalizeOp(Result); // Relegalize new nodes. @@ -1297,7 +1314,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Result = DAG.getExtLoad(ISD::EXTLOAD, dl, Node->getValueType(0), Tmp1, Tmp2, LD->getSrcValue(), LD->getSrcValueOffset(), SrcVT, - LD->isVolatile(), LD->getAlignment()); + LD->isVolatile(), LD->isNonTemporal(), + LD->getAlignment()); SDValue ValRes; if (ExtType == ISD::SEXTLOAD) ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, @@ -1325,6 +1343,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { int SVOffset = ST->getSrcValueOffset(); unsigned Alignment = ST->getAlignment(); bool isVolatile = ST->isVolatile(); + bool isNonTemporal = ST->isNonTemporal(); if (!ST->isTruncatingStore()) { if (SDNode *OptStore = OptimizeFloatStore(ST).getNode()) { @@ -1361,7 +1380,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { TLI.getTypeToPromoteTo(ISD::STORE, VT), Tmp3); Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), SVOffset, isVolatile, - Alignment); + isNonTemporal, Alignment); break; } break; @@ -1379,7 +1398,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { EVT NVT = EVT::getIntegerVT(*DAG.getContext(), StVT.getStoreSizeInBits()); Tmp3 = DAG.getZeroExtendInReg(Tmp3, dl, StVT); Result = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), - SVOffset, NVT, isVolatile, Alignment); + SVOffset, NVT, isVolatile, isNonTemporal, + Alignment); } else if (StWidth & (StWidth - 1)) { // If not storing a power-of-2 number of bits, expand as two stores. assert(!StVT.isVector() && "Unsupported truncstore!"); @@ -1399,7 +1419,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Store the bottom RoundWidth bits. Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), SVOffset, RoundVT, - isVolatile, Alignment); + isVolatile, isNonTemporal, Alignment); // Store the remaining ExtraWidth bits. IncrementSize = RoundWidth / 8; @@ -1409,6 +1429,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { DAG.getConstant(RoundWidth, TLI.getShiftAmountTy())); Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(), SVOffset + IncrementSize, ExtraVT, isVolatile, + isNonTemporal, MinAlign(Alignment, IncrementSize)); } else { // Big endian - avoid unaligned stores. @@ -1417,7 +1438,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3, DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy())); Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(), - SVOffset, RoundVT, isVolatile, Alignment); + SVOffset, RoundVT, isVolatile, isNonTemporal, + Alignment); // Store the remaining ExtraWidth bits. IncrementSize = RoundWidth / 8; @@ -1425,6 +1447,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { DAG.getIntPtrConstant(IncrementSize)); Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), SVOffset + IncrementSize, ExtraVT, isVolatile, + isNonTemporal, MinAlign(Alignment, IncrementSize)); } @@ -1457,7 +1480,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { assert(isTypeLegal(StVT) && "Do not know how to expand this store!"); Tmp3 = DAG.getNode(ISD::TRUNCATE, dl, StVT, Tmp3); Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), - SVOffset, isVolatile, Alignment); + SVOffset, isVolatile, isNonTemporal, + Alignment); break; } } @@ -1484,7 +1508,8 @@ SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) { DebugLoc dl = Op.getDebugLoc(); // Store the value to a temporary stack slot, then LOAD the returned part. SDValue StackPtr = DAG.CreateStackTemporary(Vec.getValueType()); - SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0); + SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0, + false, false, 0); // Add the offset to the index. unsigned EltSize = @@ -1500,10 +1525,12 @@ SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) { StackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, StackPtr); if (Op.getValueType().isVector()) - return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, NULL, 0); + return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, NULL, 0, + false, false, 0); else return DAG.getExtLoad(ISD::EXTLOAD, dl, Op.getValueType(), Ch, StackPtr, - NULL, 0, Vec.getValueType().getVectorElementType()); + NULL, 0, Vec.getValueType().getVectorElementType(), + false, false, 0); } SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) { @@ -1533,12 +1560,14 @@ SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) { Idx = DAG.getNode(ISD::ADD, dl, FIPtr.getValueType(), FIPtr, Idx); // If EltVT smaller than OpVT, only store the bits necessary. - if (EltVT.bitsLT(OpVT)) + if (!OpVT.isVector() && EltVT.bitsLT(OpVT)) { Stores.push_back(DAG.getTruncStore(DAG.getEntryNode(), dl, - Node->getOperand(i), Idx, SV, Offset, EltVT)); - else + Node->getOperand(i), Idx, SV, Offset, + EltVT, false, false, 0)); + } else Stores.push_back(DAG.getStore(DAG.getEntryNode(), dl, - Node->getOperand(i), Idx, SV, Offset)); + Node->getOperand(i), Idx, SV, Offset, + false, false, 0)); } SDValue StoreChain; @@ -1549,7 +1578,7 @@ SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) { StoreChain = DAG.getEntryNode(); // Result is a load from the stack slot. - return DAG.getLoad(VT, dl, StoreChain, FIPtr, SV, 0); + return DAG.getLoad(VT, dl, StoreChain, FIPtr, SV, 0, false, false, 0); } SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode* Node) { @@ -1572,12 +1601,14 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode* Node) { SDValue StackPtr = DAG.CreateStackTemporary(Tmp2.getValueType()); SDValue StorePtr = StackPtr, LoadPtr = StackPtr; SDValue Ch = - DAG.getStore(DAG.getEntryNode(), dl, Tmp2, StorePtr, NULL, 0); + DAG.getStore(DAG.getEntryNode(), dl, Tmp2, StorePtr, NULL, 0, + false, false, 0); if (Tmp2.getValueType() == MVT::f64 && TLI.isLittleEndian()) LoadPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), LoadPtr, DAG.getIntPtrConstant(4)); SignBit = DAG.getExtLoad(ISD::SEXTLOAD, dl, TLI.getPointerTy(), - Ch, LoadPtr, NULL, 0, MVT::i32); + Ch, LoadPtr, NULL, 0, MVT::i32, + false, false, 0); } SignBit = DAG.getSetCC(dl, TLI.getSetCCResultType(SignBit.getValueType()), @@ -1701,20 +1732,21 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, if (SrcSize > SlotSize) Store = DAG.getTruncStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, - SV, 0, SlotVT, false, SrcAlign); + SV, 0, SlotVT, false, false, SrcAlign); else { assert(SrcSize == SlotSize && "Invalid store"); Store = DAG.getStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, - SV, 0, false, SrcAlign); + SV, 0, false, false, SrcAlign); } // Result is a load from the stack slot. if (SlotSize == DestSize) - return DAG.getLoad(DestVT, dl, Store, FIPtr, SV, 0, false, DestAlign); + return DAG.getLoad(DestVT, dl, Store, FIPtr, SV, 0, false, false, + DestAlign); assert(SlotSize < DestSize && "Unknown extension!"); return DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, Store, FIPtr, SV, 0, SlotVT, - false, DestAlign); + false, false, DestAlign); } SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) { @@ -1729,9 +1761,11 @@ SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) { SDValue Ch = DAG.getTruncStore(DAG.getEntryNode(), dl, Node->getOperand(0), StackPtr, PseudoSourceValue::getFixedStack(SPFI), 0, - Node->getValueType(0).getVectorElementType()); + Node->getValueType(0).getVectorElementType(), + false, false, 0); return DAG.getLoad(Node->getValueType(0), dl, Ch, StackPtr, - PseudoSourceValue::getFixedStack(SPFI), 0); + PseudoSourceValue::getFixedStack(SPFI), 0, + false, false, 0); } @@ -1805,7 +1839,7 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); return DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx, PseudoSourceValue::getConstantPool(), 0, - false, Alignment); + false, false, Alignment); } if (!MoreThanTwoValues) { @@ -1943,13 +1977,16 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, } // store the lo of the constructed double - based on integer input SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl, - Op0Mapped, Lo, NULL, 0); + Op0Mapped, Lo, NULL, 0, + false, false, 0); // initial hi portion of constructed double SDValue InitialHi = DAG.getConstant(0x43300000u, MVT::i32); // store the hi of the constructed double - biased exponent - SDValue Store2=DAG.getStore(Store1, dl, InitialHi, Hi, NULL, 0); + SDValue Store2=DAG.getStore(Store1, dl, InitialHi, Hi, NULL, 0, + false, false, 0); // load the constructed double - SDValue Load = DAG.getLoad(MVT::f64, dl, Store2, StackSlot, NULL, 0); + SDValue Load = DAG.getLoad(MVT::f64, dl, Store2, StackSlot, NULL, 0, + false, false, 0); // FP constant to bias correct the final result SDValue Bias = DAG.getConstantFP(isSigned ? BitsToDouble(0x4330000080000000ULL) : @@ -2004,13 +2041,13 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, if (DestVT == MVT::f32) FudgeInReg = DAG.getLoad(MVT::f32, dl, DAG.getEntryNode(), CPIdx, PseudoSourceValue::getConstantPool(), 0, - false, Alignment); + false, false, Alignment); else { FudgeInReg = LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, DAG.getEntryNode(), CPIdx, PseudoSourceValue::getConstantPool(), 0, - MVT::f32, false, Alignment)); + MVT::f32, false, false, Alignment)); } return DAG.getNode(ISD::FADD, dl, DestVT, Tmp1, FudgeInReg); @@ -2350,16 +2387,19 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, EVT VT = Node->getValueType(0); Tmp1 = Node->getOperand(0); Tmp2 = Node->getOperand(1); - SDValue VAList = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp2, V, 0); + SDValue VAList = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp2, V, 0, + false, false, 0); // Increment the pointer, VAList, to the next vaarg Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList, DAG.getConstant(TLI.getTargetData()-> getTypeAllocSize(VT.getTypeForEVT(*DAG.getContext())), TLI.getPointerTy())); // Store the incremented VAList to the legalized pointer - Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Tmp2, V, 0); + Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Tmp2, V, 0, + false, false, 0); // Load the actual argument out of the pointer VAList - Results.push_back(DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0)); + Results.push_back(DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0, + false, false, 0)); Results.push_back(Results[0].getValue(1)); break; } @@ -2369,8 +2409,9 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, const Value *VD = cast<SrcValueSDNode>(Node->getOperand(3))->getValue(); const Value *VS = cast<SrcValueSDNode>(Node->getOperand(4))->getValue(); Tmp1 = DAG.getLoad(TLI.getPointerTy(), dl, Node->getOperand(0), - Node->getOperand(2), VS, 0); - Tmp1 = DAG.getStore(Tmp1.getValue(1), dl, Tmp1, Node->getOperand(1), VD, 0); + Node->getOperand(2), VS, 0, false, false, 0); + Tmp1 = DAG.getStore(Tmp1.getValue(1), dl, Tmp1, Node->getOperand(1), VD, 0, + false, false, 0); Results.push_back(Tmp1); break; } @@ -2767,7 +2808,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, DAG.getIntPtrConstant(1)); } else { // FIXME: We should be able to fall back to a libcall with an illegal - // type in some cases cases. + // type in some cases. // Also, we can fall back to a division in some cases, but that's a big // performance hit in the general case. llvm_unreachable("Don't know how to expand this operation yet!"); @@ -2816,15 +2857,19 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, SDValue Index = Node->getOperand(2); EVT PTy = TLI.getPointerTy(); - MachineFunction &MF = DAG.getMachineFunction(); - unsigned EntrySize = MF.getJumpTableInfo()->getEntrySize(); - Index= DAG.getNode(ISD::MUL, dl, PTy, + + const TargetData &TD = *TLI.getTargetData(); + unsigned EntrySize = + DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(TD); + + Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(EntrySize, PTy)); SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table); EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), EntrySize * 8); SDValue LD = DAG.getExtLoad(ISD::SEXTLOAD, dl, PTy, Chain, Addr, - PseudoSourceValue::getJumpTable(), 0, MemVT); + PseudoSourceValue::getJumpTable(), 0, MemVT, + false, false, 0); Addr = LD; if (TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_) { // For PIC, the sequence is: diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index 4f0fce743422a..35a7c7cedd24b 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -444,7 +444,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { NewL = DAG.getLoad(L->getAddressingMode(), dl, L->getExtensionType(), NVT, L->getChain(), L->getBasePtr(), L->getOffset(), L->getSrcValue(), L->getSrcValueOffset(), NVT, - L->isVolatile(), L->getAlignment()); + L->isVolatile(), L->isNonTemporal(), L->getAlignment()); // Legalized the chain result - switch anything that used the old chain to // use the new one. ReplaceValueWith(SDValue(N, 1), NewL.getValue(1)); @@ -456,8 +456,8 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { L->getMemoryVT(), L->getChain(), L->getBasePtr(), L->getOffset(), L->getSrcValue(), L->getSrcValueOffset(), - L->getMemoryVT(), - L->isVolatile(), L->getAlignment()); + L->getMemoryVT(), L->isVolatile(), + L->isNonTemporal(), L->getAlignment()); // Legalized the chain result - switch anything that used the old chain to // use the new one. ReplaceValueWith(SDValue(N, 1), NewL.getValue(1)); @@ -755,7 +755,8 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) { return DAG.getStore(ST->getChain(), dl, Val, ST->getBasePtr(), ST->getSrcValue(), ST->getSrcValueOffset(), - ST->isVolatile(), ST->getAlignment()); + ST->isVolatile(), ST->isNonTemporal(), + ST->getAlignment()); } @@ -1073,8 +1074,8 @@ void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo, Hi = DAG.getExtLoad(LD->getExtensionType(), dl, NVT, Chain, Ptr, LD->getSrcValue(), LD->getSrcValueOffset(), - LD->getMemoryVT(), - LD->isVolatile(), LD->getAlignment()); + LD->getMemoryVT(), LD->isVolatile(), + LD->isNonTemporal(), LD->getAlignment()); // Remember the chain. Chain = Hi.getValue(1); @@ -1382,6 +1383,6 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) { return DAG.getTruncStore(Chain, N->getDebugLoc(), Hi, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), - ST->getMemoryVT(), - ST->isVolatile(), ST->getAlignment()); + ST->getMemoryVT(), ST->isVolatile(), + ST->isNonTemporal(), ST->getAlignment()); } diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 9932cf49eb2d5..e4d123f3f65c3 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -359,7 +359,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) { SDValue Res = DAG.getExtLoad(ExtType, dl, NVT, N->getChain(), N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(), N->getMemoryVT(), N->isVolatile(), - N->getAlignment()); + N->isNonTemporal(), N->getAlignment()); // Legalized the chain result - switch anything that used the old chain to // use the new one. @@ -873,6 +873,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){ int SVOffset = N->getSrcValueOffset(); unsigned Alignment = N->getAlignment(); bool isVolatile = N->isVolatile(); + bool isNonTemporal = N->isNonTemporal(); DebugLoc dl = N->getDebugLoc(); SDValue Val = GetPromotedInteger(N->getValue()); // Get promoted value. @@ -880,7 +881,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){ // Truncate the value and store the result. return DAG.getTruncStore(Ch, dl, Val, Ptr, N->getSrcValue(), SVOffset, N->getMemoryVT(), - isVolatile, Alignment); + isVolatile, isNonTemporal, Alignment); } SDValue DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) { @@ -1500,6 +1501,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, int SVOffset = N->getSrcValueOffset(); unsigned Alignment = N->getAlignment(); bool isVolatile = N->isVolatile(); + bool isNonTemporal = N->isNonTemporal(); DebugLoc dl = N->getDebugLoc(); assert(NVT.isByteSized() && "Expanded type not byte sized!"); @@ -1508,7 +1510,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, EVT MemVT = N->getMemoryVT(); Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, - MemVT, isVolatile, Alignment); + MemVT, isVolatile, isNonTemporal, Alignment); // Remember the chain. Ch = Lo.getValue(1); @@ -1530,7 +1532,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, } else if (TLI.isLittleEndian()) { // Little-endian - low bits are at low addresses. Lo = DAG.getLoad(NVT, dl, Ch, Ptr, N->getSrcValue(), SVOffset, - isVolatile, Alignment); + isVolatile, isNonTemporal, Alignment); unsigned ExcessBits = N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits(); @@ -1542,7 +1544,8 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, DAG.getIntPtrConstant(IncrementSize)); Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, NEVT, - isVolatile, MinAlign(Alignment, IncrementSize)); + isVolatile, isNonTemporal, + MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. @@ -1560,7 +1563,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT::getIntegerVT(*DAG.getContext(), MemVT.getSizeInBits() - ExcessBits), - isVolatile, Alignment); + isVolatile, isNonTemporal, Alignment); // Increment the pointer to the other half. Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, @@ -1569,7 +1572,8 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, EVT::getIntegerVT(*DAG.getContext(), ExcessBits), - isVolatile, MinAlign(Alignment, IncrementSize)); + isVolatile, isNonTemporal, + MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. @@ -2212,6 +2216,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { int SVOffset = N->getSrcValueOffset(); unsigned Alignment = N->getAlignment(); bool isVolatile = N->isVolatile(); + bool isNonTemporal = N->isNonTemporal(); DebugLoc dl = N->getDebugLoc(); SDValue Lo, Hi; @@ -2220,13 +2225,14 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { if (N->getMemoryVT().bitsLE(NVT)) { GetExpandedInteger(N->getValue(), Lo, Hi); return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset, - N->getMemoryVT(), isVolatile, Alignment); + N->getMemoryVT(), isVolatile, isNonTemporal, + Alignment); } else if (TLI.isLittleEndian()) { // Little-endian - low bits are at low addresses. GetExpandedInteger(N->getValue(), Lo, Hi); Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset, - isVolatile, Alignment); + isVolatile, isNonTemporal, Alignment); unsigned ExcessBits = N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits(); @@ -2238,7 +2244,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { DAG.getIntPtrConstant(IncrementSize)); Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize, NEVT, - isVolatile, MinAlign(Alignment, IncrementSize)); + isVolatile, isNonTemporal, + MinAlign(Alignment, IncrementSize)); return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); } else { // Big-endian - high bits are at low addresses. Favor aligned stores at @@ -2264,7 +2271,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { // Store both the high bits and maybe some of the low bits. Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(), - SVOffset, HiVT, isVolatile, Alignment); + SVOffset, HiVT, isVolatile, isNonTemporal, + Alignment); // Increment the pointer to the other half. Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, @@ -2273,7 +2281,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset+IncrementSize, EVT::getIntegerVT(*DAG.getContext(), ExcessBits), - isVolatile, MinAlign(Alignment, IncrementSize)); + isVolatile, isNonTemporal, + MinAlign(Alignment, IncrementSize)); return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); } } @@ -2341,7 +2350,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { // FIXME: Avoid the extend by constructing the right constant pool? SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, dl, DstVT, DAG.getEntryNode(), FudgePtr, NULL, 0, MVT::f32, - false, Alignment); + false, false, Alignment); return DAG.getNode(ISD::FADD, dl, DstVT, SignedConv, Fudge); } diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 37f36a3ea3162..0d929f12c9506 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -871,9 +871,10 @@ SDValue DAGTypeLegalizer::CreateStackStoreLoad(SDValue Op, // the source and destination types. SDValue StackPtr = DAG.CreateStackTemporary(Op.getValueType(), DestVT); // Emit a store to the stack slot. - SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Op, StackPtr, NULL, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Op, StackPtr, NULL, 0, + false, false, 0); // Result is a load from the stack slot. - return DAG.getLoad(DestVT, dl, Store, StackPtr, NULL, 0); + return DAG.getLoad(DestVT, dl, Store, StackPtr, NULL, 0, false, false, 0); } /// CustomLowerNode - Replace the node's results with custom code provided diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index b5dbd41eb97ae..b0af357b17bf0 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -609,6 +609,7 @@ private: SDValue WidenVecRes_SIGN_EXTEND_INREG(SDNode* N); SDValue WidenVecRes_SELECT(SDNode* N); SDValue WidenVecRes_SELECT_CC(SDNode* N); + SDValue WidenVecRes_SETCC(SDNode* N); SDValue WidenVecRes_UNDEF(SDNode *N); SDValue WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N); SDValue WidenVecRes_VSETCC(SDNode* N); @@ -633,43 +634,33 @@ private: // Vector Widening Utilities Support: LegalizeVectorTypes.cpp //===--------------------------------------------------------------------===// - /// Helper genWidenVectorLoads - Helper function to generate a set of + /// Helper GenWidenVectorLoads - Helper function to generate a set of /// loads to load a vector with a resulting wider type. It takes - /// ExtType: Extension type - /// LdChain: list of chains for the load we have generated. - /// Chain: incoming chain for the ld vector. - /// BasePtr: base pointer to load from. - /// SV: memory disambiguation source value. - /// SVOffset: memory disambiugation offset. - /// Alignment: alignment of the memory. - /// isVolatile: volatile load. - /// LdWidth: width of memory that we want to load. - /// ResType: the wider result result type for the resulting vector. - /// dl: DebugLoc to be applied to new nodes - SDValue GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain, SDValue Chain, - SDValue BasePtr, const Value *SV, - int SVOffset, unsigned Alignment, - bool isVolatile, unsigned LdWidth, - EVT ResType, DebugLoc dl); + /// LdChain: list of chains for the load to be generated. + /// Ld: load to widen + SDValue GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain, + LoadSDNode *LD); + + /// GenWidenVectorExtLoads - Helper function to generate a set of extension + /// loads to load a ector with a resulting wider type. It takes + /// LdChain: list of chains for the load to be generated. + /// Ld: load to widen + /// ExtType: extension element type + SDValue GenWidenVectorExtLoads(SmallVector<SDValue, 16>& LdChain, + LoadSDNode *LD, ISD::LoadExtType ExtType); /// Helper genWidenVectorStores - Helper function to generate a set of /// stores to store a widen vector into non widen memory - /// It takes /// StChain: list of chains for the stores we have generated - /// Chain: incoming chain for the ld vector - /// BasePtr: base pointer to load from - /// SV: memory disambiguation source value - /// SVOffset: memory disambiugation offset - /// Alignment: alignment of the memory - /// isVolatile: volatile lod - /// ValOp: value to store - /// StWidth: width of memory that we want to store - /// dl: DebugLoc to be applied to new nodes - void GenWidenVectorStores(SmallVector<SDValue, 16>& StChain, SDValue Chain, - SDValue BasePtr, const Value *SV, - int SVOffset, unsigned Alignment, - bool isVolatile, SDValue ValOp, - unsigned StWidth, DebugLoc dl); + /// ST: store of a widen value + void GenWidenVectorStores(SmallVector<SDValue, 16>& StChain, StoreSDNode *ST); + + /// Helper genWidenVectorTruncStores - Helper function to generate a set of + /// stores to store a truncate widen vector into non widen memory + /// StChain: list of chains for the stores we have generated + /// ST: store of a widen value + void GenWidenVectorTruncStores(SmallVector<SDValue, 16>& StChain, + StoreSDNode *ST); /// Modifies a vector input (widen or narrows) to a vector of NVT. The /// input vector must have the same element type as NVT. diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp index a1b6ced0c4247..5e83b4ba33d68 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp @@ -122,10 +122,11 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo, const Value *SV = PseudoSourceValue::getFixedStack(SPFI); // Emit a store to the stack slot. - SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, SV, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, SV, 0, + false, false, 0); // Load the first half from the stack slot. - Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, SV, 0); + Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, SV, 0, false, false, 0); // Increment the pointer to the other half. unsigned IncrementSize = NOutVT.getSizeInBits() / 8; @@ -134,7 +135,7 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo, // Load the second half from the stack slot. Hi = DAG.getLoad(NOutVT, dl, Store, StackPtr, SV, IncrementSize, false, - MinAlign(Alignment, IncrementSize)); + false, MinAlign(Alignment, IncrementSize)); // Handle endianness of the load. if (TLI.isBigEndian()) @@ -205,11 +206,12 @@ void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo, int SVOffset = LD->getSrcValueOffset(); unsigned Alignment = LD->getAlignment(); bool isVolatile = LD->isVolatile(); + bool isNonTemporal = LD->isNonTemporal(); assert(NVT.isByteSized() && "Expanded type not byte sized!"); Lo = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getSrcValue(), SVOffset, - isVolatile, Alignment); + isVolatile, isNonTemporal, Alignment); // Increment the pointer to the other half. unsigned IncrementSize = NVT.getSizeInBits() / 8; @@ -217,7 +219,8 @@ void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo, DAG.getIntPtrConstant(IncrementSize)); Hi = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getSrcValue(), SVOffset+IncrementSize, - isVolatile, MinAlign(Alignment, IncrementSize)); + isVolatile, isNonTemporal, + MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. @@ -383,6 +386,7 @@ SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) { int SVOffset = St->getSrcValueOffset(); unsigned Alignment = St->getAlignment(); bool isVolatile = St->isVolatile(); + bool isNonTemporal = St->isNonTemporal(); assert(NVT.isByteSized() && "Expanded type not byte sized!"); unsigned IncrementSize = NVT.getSizeInBits() / 8; @@ -394,14 +398,15 @@ SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) { std::swap(Lo, Hi); Lo = DAG.getStore(Chain, dl, Lo, Ptr, St->getSrcValue(), SVOffset, - isVolatile, Alignment); + isVolatile, isNonTemporal, Alignment); Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!"); Hi = DAG.getStore(Chain, dl, Hi, Ptr, St->getSrcValue(), SVOffset + IncrementSize, - isVolatile, MinAlign(Alignment, IncrementSize)); + isVolatile, isNonTemporal, + MinAlign(Alignment, IncrementSize)); return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); } diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index 808bac70fda8c..8363c3af21218 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -172,7 +172,8 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) { DAG.getUNDEF(N->getBasePtr().getValueType()), N->getSrcValue(), N->getSrcValueOffset(), N->getMemoryVT().getVectorElementType(), - N->isVolatile(), N->getOriginalAlignment()); + N->isVolatile(), N->isNonTemporal(), + N->getOriginalAlignment()); // Legalized the chain result - switch anything that used the old chain to // use the new one. @@ -366,11 +367,13 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){ N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(), N->getMemoryVT().getVectorElementType(), - N->isVolatile(), N->getAlignment()); + N->isVolatile(), N->isNonTemporal(), + N->getAlignment()); return DAG.getStore(N->getChain(), dl, GetScalarizedVector(N->getOperand(1)), N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(), - N->isVolatile(), N->getOriginalAlignment()); + N->isVolatile(), N->isNonTemporal(), + N->getOriginalAlignment()); } @@ -696,17 +699,20 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, EVT VecVT = Vec.getValueType(); EVT EltVT = VecVT.getVectorElementType(); SDValue StackPtr = DAG.CreateStackTemporary(VecVT); - SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0, + false, false, 0); // Store the new element. This may be larger than the vector element type, // so use a truncating store. SDValue EltPtr = GetVectorElementPointer(StackPtr, EltVT, Idx); unsigned Alignment = TLI.getTargetData()->getPrefTypeAlignment(VecVT.getTypeForEVT(*DAG.getContext())); - Store = DAG.getTruncStore(Store, dl, Elt, EltPtr, NULL, 0, EltVT); + Store = DAG.getTruncStore(Store, dl, Elt, EltPtr, NULL, 0, EltVT, + false, false, 0); // Load the Lo part from the stack slot. - Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, NULL, 0); + Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, NULL, 0, + false, false, 0); // Increment the pointer to the other part. unsigned IncrementSize = Lo.getValueType().getSizeInBits() / 8; @@ -715,7 +721,7 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, // Load the Hi part from the stack slot. Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, NULL, 0, false, - MinAlign(Alignment, IncrementSize)); + false, MinAlign(Alignment, IncrementSize)); } void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo, @@ -743,19 +749,20 @@ void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo, EVT MemoryVT = LD->getMemoryVT(); unsigned Alignment = LD->getOriginalAlignment(); bool isVolatile = LD->isVolatile(); + bool isNonTemporal = LD->isNonTemporal(); EVT LoMemVT, HiMemVT; GetSplitDestVTs(MemoryVT, LoMemVT, HiMemVT); Lo = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, LoVT, Ch, Ptr, Offset, - SV, SVOffset, LoMemVT, isVolatile, Alignment); + SV, SVOffset, LoMemVT, isVolatile, isNonTemporal, Alignment); unsigned IncrementSize = LoMemVT.getSizeInBits()/8; Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); SVOffset += IncrementSize; Hi = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, HiVT, Ch, Ptr, Offset, - SV, SVOffset, HiMemVT, isVolatile, Alignment); + SV, SVOffset, HiMemVT, isVolatile, isNonTemporal, Alignment); // Build a factor node to remember that this load is independent of the // other one. @@ -1086,12 +1093,13 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { SDValue StackPtr = DAG.CreateStackTemporary(VecVT); int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex(); const Value *SV = PseudoSourceValue::getFixedStack(SPFI); - SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, SV, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, SV, 0, + false, false, 0); // Load back the required element. StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx); return DAG.getExtLoad(ISD::EXTLOAD, dl, N->getValueType(0), Store, StackPtr, - SV, 0, EltVT); + SV, 0, EltVT, false, false, 0); } SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) { @@ -1106,6 +1114,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) { EVT MemoryVT = N->getMemoryVT(); unsigned Alignment = N->getOriginalAlignment(); bool isVol = N->isVolatile(); + bool isNT = N->isNonTemporal(); SDValue Lo, Hi; GetSplitVector(N->getOperand(1), Lo, Hi); @@ -1116,10 +1125,10 @@ SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) { if (isTruncating) Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset, - LoMemVT, isVol, Alignment); + LoMemVT, isVol, isNT, Alignment); else Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset, - isVol, Alignment); + isVol, isNT, Alignment); // Increment the pointer to the other half. Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, @@ -1128,10 +1137,10 @@ SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) { if (isTruncating) Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset, - HiMemVT, isVol, Alignment); + HiMemVT, isVol, isNT, Alignment); else Hi = DAG.getStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset, - isVol, Alignment); + isVol, isNT, Alignment); return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); } @@ -1172,6 +1181,7 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) { case ISD::SIGN_EXTEND_INREG: Res = WidenVecRes_InregOp(N); break; case ISD::SELECT: Res = WidenVecRes_SELECT(N); break; case ISD::SELECT_CC: Res = WidenVecRes_SELECT_CC(N); break; + case ISD::SETCC: Res = WidenVecRes_SETCC(N); break; case ISD::UNDEF: Res = WidenVecRes_UNDEF(N); break; case ISD::VECTOR_SHUFFLE: Res = WidenVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N)); @@ -1241,10 +1251,96 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) { SDValue DAGTypeLegalizer::WidenVecRes_Binary(SDNode *N) { // Binary op widening. + unsigned Opcode = N->getOpcode(); + DebugLoc dl = N->getDebugLoc(); EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); - SDValue InOp1 = GetWidenedVector(N->getOperand(0)); - SDValue InOp2 = GetWidenedVector(N->getOperand(1)); - return DAG.getNode(N->getOpcode(), N->getDebugLoc(), WidenVT, InOp1, InOp2); + EVT WidenEltVT = WidenVT.getVectorElementType(); + EVT VT = WidenVT; + unsigned NumElts = VT.getVectorNumElements(); + while (!TLI.isTypeLegal(VT) && NumElts != 1) { + NumElts = NumElts / 2; + VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts); + } + + if (NumElts != 1 && !TLI.canOpTrap(N->getOpcode(), VT)) { + // Operation doesn't trap so just widen as normal. + SDValue InOp1 = GetWidenedVector(N->getOperand(0)); + SDValue InOp2 = GetWidenedVector(N->getOperand(1)); + return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2); + } else if (NumElts == 1) { + // No legal vector version so unroll the vector operation and then widen. + return DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements()); + } else { + // Since the operation can trap, apply operation on the original vector. + SDValue InOp1 = GetWidenedVector(N->getOperand(0)); + SDValue InOp2 = GetWidenedVector(N->getOperand(1)); + unsigned CurNumElts = N->getValueType(0).getVectorNumElements(); + + SmallVector<SDValue, 16> ConcatOps(CurNumElts); + unsigned ConcatEnd = 0; // Current ConcatOps index. + unsigned Idx = 0; // Current Idx into input vectors. + while (CurNumElts != 0) { + while (CurNumElts >= NumElts) { + SDValue EOp1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, InOp1, + DAG.getIntPtrConstant(Idx)); + SDValue EOp2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, InOp2, + DAG.getIntPtrConstant(Idx)); + ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2); + Idx += NumElts; + CurNumElts -= NumElts; + } + EVT PrevVecVT = VT; + do { + NumElts = NumElts / 2; + VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts); + } while (!TLI.isTypeLegal(VT) && NumElts != 1); + + if (NumElts == 1) { + // Since we are using concat vector, build a vector from the scalar ops. + SDValue VecOp = DAG.getUNDEF(PrevVecVT); + for (unsigned i = 0; i != CurNumElts; ++i, ++Idx) { + SDValue EOp1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT, + InOp1, DAG.getIntPtrConstant(Idx)); + SDValue EOp2 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT, + InOp2, DAG.getIntPtrConstant(Idx)); + VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, PrevVecVT, VecOp, + DAG.getNode(Opcode, dl, WidenEltVT, EOp1, EOp2), + DAG.getIntPtrConstant(i)); + } + CurNumElts = 0; + ConcatOps[ConcatEnd++] = VecOp; + } + } + + // Check to see if we have a single operation with the widen type. + if (ConcatEnd == 1) { + VT = ConcatOps[0].getValueType(); + if (VT == WidenVT) + return ConcatOps[0]; + } + + // Rebuild vector to one with the widen type + Idx = ConcatEnd - 1; + while (Idx != 0) { + VT = ConcatOps[Idx--].getValueType(); + while (Idx != 0 && ConcatOps[Idx].getValueType() == VT) + --Idx; + if (Idx != 0) { + VT = ConcatOps[Idx].getValueType(); + ConcatOps[Idx+1] = DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, + &ConcatOps[Idx+1], ConcatEnd - Idx - 1); + ConcatEnd = Idx + 2; + } + } + + unsigned NumOps = WidenVT.getVectorNumElements()/VT.getVectorNumElements(); + if (NumOps != ConcatEnd ) { + SDValue UndefVal = DAG.getUNDEF(VT); + for (unsigned j = ConcatEnd; j < NumOps; ++j) + ConcatOps[j] = UndefVal; + } + return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &ConcatOps[0], NumOps); + } } SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) { @@ -1655,68 +1751,24 @@ SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) { SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) { LoadSDNode *LD = cast<LoadSDNode>(N); - EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), LD->getValueType(0)); - EVT LdVT = LD->getMemoryVT(); - DebugLoc dl = N->getDebugLoc(); - assert(LdVT.isVector() && WidenVT.isVector()); - - // Load information - SDValue Chain = LD->getChain(); - SDValue BasePtr = LD->getBasePtr(); - int SVOffset = LD->getSrcValueOffset(); - unsigned Align = LD->getAlignment(); - bool isVolatile = LD->isVolatile(); - const Value *SV = LD->getSrcValue(); ISD::LoadExtType ExtType = LD->getExtensionType(); SDValue Result; SmallVector<SDValue, 16> LdChain; // Chain for the series of load - if (ExtType != ISD::NON_EXTLOAD) { - // For extension loads, we can not play the tricks of chopping legal - // vector types and bit cast it to the right type. Instead, we unroll - // the load and build a vector. - EVT EltVT = WidenVT.getVectorElementType(); - EVT LdEltVT = LdVT.getVectorElementType(); - unsigned NumElts = LdVT.getVectorNumElements(); - - // Load each element and widen - unsigned WidenNumElts = WidenVT.getVectorNumElements(); - SmallVector<SDValue, 16> Ops(WidenNumElts); - unsigned Increment = LdEltVT.getSizeInBits() / 8; - Ops[0] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr, SV, SVOffset, - LdEltVT, isVolatile, Align); - LdChain.push_back(Ops[0].getValue(1)); - unsigned i = 0, Offset = Increment; - for (i=1; i < NumElts; ++i, Offset += Increment) { - SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), - BasePtr, DAG.getIntPtrConstant(Offset)); - Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr, SV, - SVOffset + Offset, LdEltVT, isVolatile, Align); - LdChain.push_back(Ops[i].getValue(1)); - } - - // Fill the rest with undefs - SDValue UndefVal = DAG.getUNDEF(EltVT); - for (; i != WidenNumElts; ++i) - Ops[i] = UndefVal; - - Result = DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], Ops.size()); - } else { - assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType()); - unsigned int LdWidth = LdVT.getSizeInBits(); - Result = GenWidenVectorLoads(LdChain, Chain, BasePtr, SV, SVOffset, - Align, isVolatile, LdWidth, WidenVT, dl); - } - - // If we generate a single load, we can use that for the chain. Otherwise, - // build a factor node to remember the multiple loads are independent and - // chain to that. - SDValue NewChain; - if (LdChain.size() == 1) - NewChain = LdChain[0]; - else - NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &LdChain[0], - LdChain.size()); + if (ExtType != ISD::NON_EXTLOAD) + Result = GenWidenVectorExtLoads(LdChain, LD, ExtType); + else + Result = GenWidenVectorLoads(LdChain, LD); + + // If we generate a single load, we can use that for the chain. Otherwise, + // build a factor node to remember the multiple loads are independent and + // chain to that. + SDValue NewChain; + if (LdChain.size() == 1) + NewChain = LdChain[0]; + else + NewChain = DAG.getNode(ISD::TokenFactor, LD->getDebugLoc(), MVT::Other, + &LdChain[0], LdChain.size()); // Modified the chain - switch anything that used the old chain to use // the new one. @@ -1762,6 +1814,14 @@ SDValue DAGTypeLegalizer::WidenVecRes_SELECT_CC(SDNode *N) { N->getOperand(1), InOp1, InOp2, N->getOperand(4)); } +SDValue DAGTypeLegalizer::WidenVecRes_SETCC(SDNode *N) { + EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); + SDValue InOp1 = GetWidenedVector(N->getOperand(0)); + SDValue InOp2 = GetWidenedVector(N->getOperand(1)); + return DAG.getNode(ISD::SETCC, N->getDebugLoc(), WidenVT, + InOp1, InOp2, N->getOperand(2)); +} + SDValue DAGTypeLegalizer::WidenVecRes_UNDEF(SDNode *N) { EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); return DAG.getUNDEF(WidenVT); @@ -1954,57 +2014,17 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) { // We have to widen the value but we want only to store the original // vector type. StoreSDNode *ST = cast<StoreSDNode>(N); - SDValue Chain = ST->getChain(); - SDValue BasePtr = ST->getBasePtr(); - const Value *SV = ST->getSrcValue(); - int SVOffset = ST->getSrcValueOffset(); - unsigned Align = ST->getAlignment(); - bool isVolatile = ST->isVolatile(); - SDValue ValOp = GetWidenedVector(ST->getValue()); - DebugLoc dl = N->getDebugLoc(); - - EVT StVT = ST->getMemoryVT(); - EVT ValVT = ValOp.getValueType(); - // It must be true that we the widen vector type is bigger than where - // we need to store. - assert(StVT.isVector() && ValOp.getValueType().isVector()); - assert(StVT.bitsLT(ValOp.getValueType())); SmallVector<SDValue, 16> StChain; - if (ST->isTruncatingStore()) { - // For truncating stores, we can not play the tricks of chopping legal - // vector types and bit cast it to the right type. Instead, we unroll - // the store. - EVT StEltVT = StVT.getVectorElementType(); - EVT ValEltVT = ValVT.getVectorElementType(); - unsigned Increment = ValEltVT.getSizeInBits() / 8; - unsigned NumElts = StVT.getVectorNumElements(); - SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp, - DAG.getIntPtrConstant(0)); - StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, BasePtr, SV, - SVOffset, StEltVT, - isVolatile, Align)); - unsigned Offset = Increment; - for (unsigned i=1; i < NumElts; ++i, Offset += Increment) { - SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), - BasePtr, DAG.getIntPtrConstant(Offset)); - SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp, - DAG.getIntPtrConstant(0)); - StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, NewBasePtr, SV, - SVOffset + Offset, StEltVT, - isVolatile, MinAlign(Align, Offset))); - } - } - else { - assert(StVT.getVectorElementType() == ValVT.getVectorElementType()); - // Store value - GenWidenVectorStores(StChain, Chain, BasePtr, SV, SVOffset, - Align, isVolatile, ValOp, StVT.getSizeInBits(), dl); - } + if (ST->isTruncatingStore()) + GenWidenVectorTruncStores(StChain, ST); + else + GenWidenVectorStores(StChain, ST); + if (StChain.size() == 1) return StChain[0]; else - return DAG.getNode(ISD::TokenFactor, dl, + return DAG.getNode(ISD::TokenFactor, ST->getDebugLoc(), MVT::Other,&StChain[0],StChain.size()); } @@ -2012,179 +2032,390 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) { // Vector Widening Utilities //===----------------------------------------------------------------------===// +// Utility function to find the type to chop up a widen vector for load/store +// TLI: Target lowering used to determine legal types. +// Width: Width left need to load/store. +// WidenVT: The widen vector type to load to/store from +// Align: If 0, don't allow use of a wider type +// WidenEx: If Align is not 0, the amount additional we can load/store from. + +static EVT FindMemType(SelectionDAG& DAG, const TargetLowering &TLI, + unsigned Width, EVT WidenVT, + unsigned Align = 0, unsigned WidenEx = 0) { + EVT WidenEltVT = WidenVT.getVectorElementType(); + unsigned WidenWidth = WidenVT.getSizeInBits(); + unsigned WidenEltWidth = WidenEltVT.getSizeInBits(); + unsigned AlignInBits = Align*8; + + // If we have one element to load/store, return it. + EVT RetVT = WidenEltVT; + if (Width == WidenEltWidth) + return RetVT; + + // See if there is larger legal integer than the element type to load/store + unsigned VT; + for (VT = (unsigned)MVT::LAST_INTEGER_VALUETYPE; + VT >= (unsigned)MVT::FIRST_INTEGER_VALUETYPE; --VT) { + EVT MemVT((MVT::SimpleValueType) VT); + unsigned MemVTWidth = MemVT.getSizeInBits(); + if (MemVT.getSizeInBits() <= WidenEltWidth) + break; + if (TLI.isTypeLegal(MemVT) && (WidenWidth % MemVTWidth) == 0 && + (MemVTWidth <= Width || + (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) { + RetVT = MemVT; + break; + } + } -// Utility function to find a vector type and its associated element -// type from a preferred width and whose vector type must be the same size -// as the VecVT. -// TLI: Target lowering used to determine legal types. -// Width: Preferred width to store. -// VecVT: Vector value type whose size we must match. -// Returns NewVecVT and NewEltVT - the vector type and its associated -// element type. -static void FindAssocWidenVecType(SelectionDAG& DAG, - const TargetLowering &TLI, unsigned Width, - EVT VecVT, - EVT& NewEltVT, EVT& NewVecVT) { - unsigned EltWidth = Width + 1; - if (TLI.isTypeLegal(VecVT)) { - // We start with the preferred with, making it a power of 2 and find a - // legal vector type of that width. If not, we reduce it by another of 2. - // For incoming type is legal, this process will end as a vector of the - // smallest loadable type should always be legal. - do { - assert(EltWidth > 0); - EltWidth = 1 << Log2_32(EltWidth - 1); - NewEltVT = EVT::getIntegerVT(*DAG.getContext(), EltWidth); - unsigned NumElts = VecVT.getSizeInBits() / EltWidth; - NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewEltVT, NumElts); - } while (!TLI.isTypeLegal(NewVecVT) || - VecVT.getSizeInBits() != NewVecVT.getSizeInBits()); - } else { - // The incoming vector type is illegal and is the result of widening - // a vector to a power of 2. In this case, we will use the preferred - // with as long as it is a multiple of the incoming vector length. - // The legalization process will eventually make this into a legal type - // and remove the illegal bit converts (which would turn to stack converts - // if they are allow to exist). - do { - assert(EltWidth > 0); - EltWidth = 1 << Log2_32(EltWidth - 1); - NewEltVT = EVT::getIntegerVT(*DAG.getContext(), EltWidth); - unsigned NumElts = VecVT.getSizeInBits() / EltWidth; - NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewEltVT, NumElts); - } while (!TLI.isTypeLegal(NewEltVT) || - VecVT.getSizeInBits() != NewVecVT.getSizeInBits()); + // See if there is a larger vector type to load/store that has the same vector + // element type and is evenly divisible with the WidenVT. + for (VT = (unsigned)MVT::LAST_VECTOR_VALUETYPE; + VT >= (unsigned)MVT::FIRST_VECTOR_VALUETYPE; --VT) { + EVT MemVT = (MVT::SimpleValueType) VT; + unsigned MemVTWidth = MemVT.getSizeInBits(); + if (TLI.isTypeLegal(MemVT) && WidenEltVT == MemVT.getVectorElementType() && + (WidenWidth % MemVTWidth) == 0 && + (MemVTWidth <= Width || + (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) { + if (RetVT.getSizeInBits() < MemVTWidth || MemVT == WidenVT) + return MemVT; + } } + + return RetVT; +} + +// Builds a vector type from scalar loads +// VecTy: Resulting Vector type +// LDOps: Load operators to build a vector type +// [Start,End) the list of loads to use. +static SDValue BuildVectorFromScalar(SelectionDAG& DAG, EVT VecTy, + SmallVector<SDValue, 16>& LdOps, + unsigned Start, unsigned End) { + DebugLoc dl = LdOps[Start].getDebugLoc(); + EVT LdTy = LdOps[Start].getValueType(); + unsigned Width = VecTy.getSizeInBits(); + unsigned NumElts = Width / LdTy.getSizeInBits(); + EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), LdTy, NumElts); + + unsigned Idx = 1; + SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT,LdOps[Start]); + + for (unsigned i = Start + 1; i != End; ++i) { + EVT NewLdTy = LdOps[i].getValueType(); + if (NewLdTy != LdTy) { + NumElts = Width / NewLdTy.getSizeInBits(); + NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewLdTy, NumElts); + VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, VecOp); + // Readjust position and vector position based on new load type + Idx = Idx * LdTy.getSizeInBits() / NewLdTy.getSizeInBits(); + LdTy = NewLdTy; + } + VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, VecOp, LdOps[i], + DAG.getIntPtrConstant(Idx++)); + } + return DAG.getNode(ISD::BIT_CONVERT, dl, VecTy, VecOp); } SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain, - SDValue Chain, - SDValue BasePtr, - const Value *SV, - int SVOffset, - unsigned Alignment, - bool isVolatile, - unsigned LdWidth, - EVT ResType, - DebugLoc dl) { + LoadSDNode * LD) { // The strategy assumes that we can efficiently load powers of two widths. - // The routines chops the vector into the largest power of 2 load and - // can be inserted into a legal vector and then cast the result into the - // vector type we want. This avoids unnecessary stack converts. + // The routines chops the vector into the largest vector loads with the same + // element type or scalar loads and then recombines it to the widen vector + // type. + EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), LD->getValueType(0)); + unsigned WidenWidth = WidenVT.getSizeInBits(); + EVT LdVT = LD->getMemoryVT(); + DebugLoc dl = LD->getDebugLoc(); + assert(LdVT.isVector() && WidenVT.isVector()); + assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType()); - // TODO: If the Ldwidth is legal, alignment is the same as the LdWidth, and - // the load is nonvolatile, we an use a wider load for the value. + // Load information + SDValue Chain = LD->getChain(); + SDValue BasePtr = LD->getBasePtr(); + int SVOffset = LD->getSrcValueOffset(); + unsigned Align = LD->getAlignment(); + bool isVolatile = LD->isVolatile(); + bool isNonTemporal = LD->isNonTemporal(); + const Value *SV = LD->getSrcValue(); + + int LdWidth = LdVT.getSizeInBits(); + int WidthDiff = WidenWidth - LdWidth; // Difference + unsigned LdAlign = (isVolatile) ? 0 : Align; // Allow wider loads // Find the vector type that can load from. - EVT NewEltVT, NewVecVT; - unsigned NewEltVTWidth; - FindAssocWidenVecType(DAG, TLI, LdWidth, ResType, NewEltVT, NewVecVT); - NewEltVTWidth = NewEltVT.getSizeInBits(); - - SDValue LdOp = DAG.getLoad(NewEltVT, dl, Chain, BasePtr, SV, SVOffset, - isVolatile, Alignment); - SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp); + EVT NewVT = FindMemType(DAG, TLI, LdWidth, WidenVT, LdAlign, WidthDiff); + int NewVTWidth = NewVT.getSizeInBits(); + SDValue LdOp = DAG.getLoad(NewVT, dl, Chain, BasePtr, SV, SVOffset, + isVolatile, isNonTemporal, Align); LdChain.push_back(LdOp.getValue(1)); // Check if we can load the element with one instruction - if (LdWidth == NewEltVTWidth) { - return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp); + if (LdWidth <= NewVTWidth) { + if (NewVT.isVector()) { + if (NewVT != WidenVT) { + assert(WidenWidth % NewVTWidth == 0); + unsigned NumConcat = WidenWidth / NewVTWidth; + SmallVector<SDValue, 16> ConcatOps(NumConcat); + SDValue UndefVal = DAG.getUNDEF(NewVT); + ConcatOps[0] = LdOp; + for (unsigned i = 1; i != NumConcat; ++i) + ConcatOps[i] = UndefVal; + return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &ConcatOps[0], + NumConcat); + } else + return LdOp; + } else { + unsigned NumElts = WidenWidth / LdWidth; + EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts); + SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp); + return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, VecOp); + } } - unsigned Idx = 1; - LdWidth -= NewEltVTWidth; + // Load vector by using multiple loads from largest vector to scalar + SmallVector<SDValue, 16> LdOps; + LdOps.push_back(LdOp); + + LdWidth -= NewVTWidth; unsigned Offset = 0; while (LdWidth > 0) { - unsigned Increment = NewEltVTWidth / 8; + unsigned Increment = NewVTWidth / 8; Offset += Increment; BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, DAG.getIntPtrConstant(Increment)); - if (LdWidth < NewEltVTWidth) { - // Our current type we are using is too large, use a smaller size by - // using a smaller power of 2 - unsigned oNewEltVTWidth = NewEltVTWidth; - FindAssocWidenVecType(DAG, TLI, LdWidth, ResType, NewEltVT, NewVecVT); - NewEltVTWidth = NewEltVT.getSizeInBits(); - // Readjust position and vector position based on new load type - Idx = Idx * (oNewEltVTWidth/NewEltVTWidth); - VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, VecOp); + if (LdWidth < NewVTWidth) { + // Our current type we are using is too large, find a better size + NewVT = FindMemType(DAG, TLI, LdWidth, WidenVT, LdAlign, WidthDiff); + NewVTWidth = NewVT.getSizeInBits(); } - SDValue LdOp = DAG.getLoad(NewEltVT, dl, Chain, BasePtr, SV, - SVOffset+Offset, isVolatile, - MinAlign(Alignment, Offset)); + SDValue LdOp = DAG.getLoad(NewVT, dl, Chain, BasePtr, SV, + SVOffset+Offset, isVolatile, + isNonTemporal, MinAlign(Align, Increment)); LdChain.push_back(LdOp.getValue(1)); - VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, VecOp, LdOp, - DAG.getIntPtrConstant(Idx++)); + LdOps.push_back(LdOp); - LdWidth -= NewEltVTWidth; + LdWidth -= NewVTWidth; } - return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp); -} + // Build the vector from the loads operations + unsigned End = LdOps.size(); + if (LdOps[0].getValueType().isVector()) { + // If the load contains vectors, build the vector using concat vector. + // All of the vectors used to loads are power of 2 and the scalars load + // can be combined to make a power of 2 vector. + SmallVector<SDValue, 16> ConcatOps(End); + int i = End - 1; + int Idx = End; + EVT LdTy = LdOps[i].getValueType(); + // First combine the scalar loads to a vector + if (!LdTy.isVector()) { + for (--i; i >= 0; --i) { + LdTy = LdOps[i].getValueType(); + if (LdTy.isVector()) + break; + } + ConcatOps[--Idx] = BuildVectorFromScalar(DAG, LdTy, LdOps, i+1, End); + } + ConcatOps[--Idx] = LdOps[i]; + for (--i; i >= 0; --i) { + EVT NewLdTy = LdOps[i].getValueType(); + if (NewLdTy != LdTy) { + // Create a larger vector + ConcatOps[End-1] = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewLdTy, + &ConcatOps[Idx], End - Idx); + Idx = End - 1; + LdTy = NewLdTy; + } + ConcatOps[--Idx] = LdOps[i]; + } -void DAGTypeLegalizer::GenWidenVectorStores(SmallVector<SDValue, 16>& StChain, - SDValue Chain, - SDValue BasePtr, - const Value *SV, - int SVOffset, - unsigned Alignment, - bool isVolatile, - SDValue ValOp, - unsigned StWidth, - DebugLoc dl) { - // Breaks the stores into a series of power of 2 width stores. For any - // width, we convert the vector to the vector of element size that we - // want to store. This avoids requiring a stack convert. - - // Find a width of the element type we can store with - EVT WidenVT = ValOp.getValueType(); - EVT NewEltVT, NewVecVT; - - FindAssocWidenVecType(DAG, TLI, StWidth, WidenVT, NewEltVT, NewVecVT); - unsigned NewEltVTWidth = NewEltVT.getSizeInBits(); - - SDValue VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, ValOp); - SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, VecOp, - DAG.getIntPtrConstant(0)); - SDValue StOp = DAG.getStore(Chain, dl, EOp, BasePtr, SV, SVOffset, - isVolatile, Alignment); - StChain.push_back(StOp); + if (WidenWidth != LdTy.getSizeInBits()*(End - Idx)) { + // We need to fill the rest with undefs to build the vector + unsigned NumOps = WidenWidth / LdTy.getSizeInBits(); + SmallVector<SDValue, 16> WidenOps(NumOps); + SDValue UndefVal = DAG.getUNDEF(LdTy); + unsigned i = 0; + for (; i != End-Idx; ++i) + WidenOps[i] = ConcatOps[Idx+i]; + for (; i != NumOps; ++i) + WidenOps[i] = UndefVal; + return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &WidenOps[0],NumOps); + } else + return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, + &ConcatOps[Idx], End - Idx); + } else // All the loads are scalar loads. + return BuildVectorFromScalar(DAG, WidenVT, LdOps, 0, End); +} + +SDValue +DAGTypeLegalizer::GenWidenVectorExtLoads(SmallVector<SDValue, 16>& LdChain, + LoadSDNode * LD, + ISD::LoadExtType ExtType) { + // For extension loads, it may not be more efficient to chop up the vector + // and then extended it. Instead, we unroll the load and build a new vector. + EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),LD->getValueType(0)); + EVT LdVT = LD->getMemoryVT(); + DebugLoc dl = LD->getDebugLoc(); + assert(LdVT.isVector() && WidenVT.isVector()); - // Check if we are done - if (StWidth == NewEltVTWidth) { - return; + // Load information + SDValue Chain = LD->getChain(); + SDValue BasePtr = LD->getBasePtr(); + int SVOffset = LD->getSrcValueOffset(); + unsigned Align = LD->getAlignment(); + bool isVolatile = LD->isVolatile(); + bool isNonTemporal = LD->isNonTemporal(); + const Value *SV = LD->getSrcValue(); + + EVT EltVT = WidenVT.getVectorElementType(); + EVT LdEltVT = LdVT.getVectorElementType(); + unsigned NumElts = LdVT.getVectorNumElements(); + + // Load each element and widen + unsigned WidenNumElts = WidenVT.getVectorNumElements(); + SmallVector<SDValue, 16> Ops(WidenNumElts); + unsigned Increment = LdEltVT.getSizeInBits() / 8; + Ops[0] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr, SV, SVOffset, + LdEltVT, isVolatile, isNonTemporal, Align); + LdChain.push_back(Ops[0].getValue(1)); + unsigned i = 0, Offset = Increment; + for (i=1; i < NumElts; ++i, Offset += Increment) { + SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), + BasePtr, DAG.getIntPtrConstant(Offset)); + Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr, SV, + SVOffset + Offset, LdEltVT, isVolatile, + isNonTemporal, Align); + LdChain.push_back(Ops[i].getValue(1)); } - unsigned Idx = 1; - StWidth -= NewEltVTWidth; - unsigned Offset = 0; + // Fill the rest with undefs + SDValue UndefVal = DAG.getUNDEF(EltVT); + for (; i != WidenNumElts; ++i) + Ops[i] = UndefVal; - while (StWidth > 0) { - unsigned Increment = NewEltVTWidth / 8; - Offset += Increment; - BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, - DAG.getIntPtrConstant(Increment)); + return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], Ops.size()); +} - if (StWidth < NewEltVTWidth) { - // Our current type we are using is too large, use a smaller size by - // using a smaller power of 2 - unsigned oNewEltVTWidth = NewEltVTWidth; - FindAssocWidenVecType(DAG, TLI, StWidth, WidenVT, NewEltVT, NewVecVT); - NewEltVTWidth = NewEltVT.getSizeInBits(); - // Readjust position and vector position based on new load type - Idx = Idx * (oNewEltVTWidth/NewEltVTWidth); - VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, VecOp); - } - EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, VecOp, +void DAGTypeLegalizer::GenWidenVectorStores(SmallVector<SDValue, 16>& StChain, + StoreSDNode *ST) { + // The strategy assumes that we can efficiently store powers of two widths. + // The routines chops the vector into the largest vector stores with the same + // element type or scalar stores. + SDValue Chain = ST->getChain(); + SDValue BasePtr = ST->getBasePtr(); + const Value *SV = ST->getSrcValue(); + int SVOffset = ST->getSrcValueOffset(); + unsigned Align = ST->getAlignment(); + bool isVolatile = ST->isVolatile(); + bool isNonTemporal = ST->isNonTemporal(); + SDValue ValOp = GetWidenedVector(ST->getValue()); + DebugLoc dl = ST->getDebugLoc(); + + EVT StVT = ST->getMemoryVT(); + unsigned StWidth = StVT.getSizeInBits(); + EVT ValVT = ValOp.getValueType(); + unsigned ValWidth = ValVT.getSizeInBits(); + EVT ValEltVT = ValVT.getVectorElementType(); + unsigned ValEltWidth = ValEltVT.getSizeInBits(); + assert(StVT.getVectorElementType() == ValEltVT); + + int Idx = 0; // current index to store + unsigned Offset = 0; // offset from base to store + while (StWidth != 0) { + // Find the largest vector type we can store with + EVT NewVT = FindMemType(DAG, TLI, StWidth, ValVT); + unsigned NewVTWidth = NewVT.getSizeInBits(); + unsigned Increment = NewVTWidth / 8; + if (NewVT.isVector()) { + unsigned NumVTElts = NewVT.getVectorNumElements(); + do { + SDValue EOp = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NewVT, ValOp, + DAG.getIntPtrConstant(Idx)); + StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, SV, + SVOffset + Offset, isVolatile, + isNonTemporal, + MinAlign(Align, Offset))); + StWidth -= NewVTWidth; + Offset += Increment; + Idx += NumVTElts; + BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, + DAG.getIntPtrConstant(Increment)); + } while (StWidth != 0 && StWidth >= NewVTWidth); + } else { + // Cast the vector to the scalar type we can store + unsigned NumElts = ValWidth / NewVTWidth; + EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts); + SDValue VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, ValOp); + // Readjust index position based on new vector type + Idx = Idx * ValEltWidth / NewVTWidth; + do { + SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, VecOp, DAG.getIntPtrConstant(Idx++)); - StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, SV, - SVOffset + Offset, isVolatile, - MinAlign(Alignment, Offset))); - StWidth -= NewEltVTWidth; + StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, SV, + SVOffset + Offset, isVolatile, + isNonTemporal, MinAlign(Align, Offset))); + StWidth -= NewVTWidth; + Offset += Increment; + BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, + DAG.getIntPtrConstant(Increment)); + } while (StWidth != 0 && StWidth >= NewVTWidth); + // Restore index back to be relative to the original widen element type + Idx = Idx * NewVTWidth / ValEltWidth; + } + } +} + +void +DAGTypeLegalizer::GenWidenVectorTruncStores(SmallVector<SDValue, 16>& StChain, + StoreSDNode *ST) { + // For extension loads, it may not be more efficient to truncate the vector + // and then store it. Instead, we extract each element and then store it. + SDValue Chain = ST->getChain(); + SDValue BasePtr = ST->getBasePtr(); + const Value *SV = ST->getSrcValue(); + int SVOffset = ST->getSrcValueOffset(); + unsigned Align = ST->getAlignment(); + bool isVolatile = ST->isVolatile(); + bool isNonTemporal = ST->isNonTemporal(); + SDValue ValOp = GetWidenedVector(ST->getValue()); + DebugLoc dl = ST->getDebugLoc(); + + EVT StVT = ST->getMemoryVT(); + EVT ValVT = ValOp.getValueType(); + + // It must be true that we the widen vector type is bigger than where + // we need to store. + assert(StVT.isVector() && ValOp.getValueType().isVector()); + assert(StVT.bitsLT(ValOp.getValueType())); + + // For truncating stores, we can not play the tricks of chopping legal + // vector types and bit cast it to the right type. Instead, we unroll + // the store. + EVT StEltVT = StVT.getVectorElementType(); + EVT ValEltVT = ValVT.getVectorElementType(); + unsigned Increment = ValEltVT.getSizeInBits() / 8; + unsigned NumElts = StVT.getVectorNumElements(); + SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp, + DAG.getIntPtrConstant(0)); + StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, BasePtr, SV, + SVOffset, StEltVT, + isVolatile, isNonTemporal, Align)); + unsigned Offset = Increment; + for (unsigned i=1; i < NumElts; ++i, Offset += Increment) { + SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), + BasePtr, DAG.getIntPtrConstant(Offset)); + SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp, + DAG.getIntPtrConstant(0)); + StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, NewBasePtr, SV, + SVOffset + Offset, StEltVT, + isVolatile, isNonTemporal, + MinAlign(Align, Offset))); } } diff --git a/lib/CodeGen/SelectionDAG/Makefile b/lib/CodeGen/SelectionDAG/Makefile index 4706e685293fa..ea716fdaabbab 100644 --- a/lib/CodeGen/SelectionDAG/Makefile +++ b/lib/CodeGen/SelectionDAG/Makefile @@ -9,6 +9,5 @@ LEVEL = ../../.. LIBRARYNAME = LLVMSelectionDAG -CXXFLAGS = -fno-rtti include $(LEVEL)/Makefile.common diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index dea59937198bb..3f1766d9e9f2b 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -345,6 +345,15 @@ void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle, ++NumBacktracks; } +static bool isOperandOf(const SUnit *SU, SDNode *N) { + for (const SDNode *SUNode = SU->getNode(); SUNode; + SUNode = SUNode->getFlaggedNode()) { + if (SUNode->isOperandOf(N)) + return true; + } + return false; +} + /// CopyAndMoveSuccessors - Clone the specified node and move its scheduled /// successors to the newly created node. SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) { @@ -427,8 +436,7 @@ SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) { I != E; ++I) { if (I->isCtrl()) ChainPreds.push_back(*I); - else if (I->getSUnit()->getNode() && - I->getSUnit()->getNode()->isOperandOf(LoadNode)) + else if (isOperandOf(I->getSUnit(), LoadNode)) LoadPreds.push_back(*I); else NodePreds.push_back(*I); @@ -1034,9 +1042,9 @@ namespace { // CopyToReg should be close to its uses to facilitate coalescing and // avoid spilling. return 0; - if (Opc == TargetInstrInfo::EXTRACT_SUBREG || - Opc == TargetInstrInfo::SUBREG_TO_REG || - Opc == TargetInstrInfo::INSERT_SUBREG) + if (Opc == TargetOpcode::EXTRACT_SUBREG || + Opc == TargetOpcode::SUBREG_TO_REG || + Opc == TargetOpcode::INSERT_SUBREG) // EXTRACT_SUBREG, INSERT_SUBREG, and SUBREG_TO_REG nodes should be // close to their uses to facilitate coalescing. return 0; @@ -1437,7 +1445,7 @@ void RegReductionPriorityQueue<SF>::AddPseudoTwoAddrDeps() { while (SuccSU->Succs.size() == 1 && SuccSU->getNode()->isMachineOpcode() && SuccSU->getNode()->getMachineOpcode() == - TargetInstrInfo::COPY_TO_REGCLASS) + TargetOpcode::COPY_TO_REGCLASS) SuccSU = SuccSU->Succs.front().getSUnit(); // Don't constrain non-instruction nodes. if (!SuccSU->getNode() || !SuccSU->getNode()->isMachineOpcode()) @@ -1451,9 +1459,9 @@ void RegReductionPriorityQueue<SF>::AddPseudoTwoAddrDeps() { // Don't constrain EXTRACT_SUBREG, INSERT_SUBREG, and SUBREG_TO_REG; // these may be coalesced away. We want them close to their uses. unsigned SuccOpc = SuccSU->getNode()->getMachineOpcode(); - if (SuccOpc == TargetInstrInfo::EXTRACT_SUBREG || - SuccOpc == TargetInstrInfo::INSERT_SUBREG || - SuccOpc == TargetInstrInfo::SUBREG_TO_REG) + if (SuccOpc == TargetOpcode::EXTRACT_SUBREG || + SuccOpc == TargetOpcode::INSERT_SUBREG || + SuccOpc == TargetOpcode::SUBREG_TO_REG) continue; if ((!canClobber(SuccSU, DUSU) || (hasCopyToRegUse(SU) && !hasCopyToRegUse(SuccSU)) || diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index f1b6f1e831fdc..43cf37ee48073 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -829,6 +829,7 @@ void SelectionDAG::clear() { EntryNode.UseList = 0; AllNodes.push_back(&EntryNode); Root = getEntryNode(); + delete Ordering; Ordering = new SDNodeOrdering(); } @@ -1925,19 +1926,28 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, const APInt &Mask, } case ISD::SREM: if (ConstantSDNode *Rem = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { - const APInt &RA = Rem->getAPIntValue(); - if (RA.isPowerOf2() || (-RA).isPowerOf2()) { - APInt LowBits = RA.isStrictlyPositive() ? (RA - 1) : ~RA; + const APInt &RA = Rem->getAPIntValue().abs(); + if (RA.isPowerOf2()) { + APInt LowBits = RA - 1; APInt Mask2 = LowBits | APInt::getSignBit(BitWidth); ComputeMaskedBits(Op.getOperand(0), Mask2,KnownZero2,KnownOne2,Depth+1); - // If the sign bit of the first operand is zero, the sign bit of - // the result is zero. If the first operand has no one bits below - // the second operand's single 1 bit, its sign will be zero. + // The low bits of the first operand are unchanged by the srem. + KnownZero = KnownZero2 & LowBits; + KnownOne = KnownOne2 & LowBits; + + // If the first operand is non-negative or has all low bits zero, then + // the upper bits are all zero. if (KnownZero2[BitWidth-1] || ((KnownZero2 & LowBits) == LowBits)) - KnownZero2 |= ~LowBits; + KnownZero |= ~LowBits; - KnownZero |= KnownZero2 & Mask; + // If the first operand is negative and not all low bits are zero, then + // the upper bits are all one. + if (KnownOne2[BitWidth-1] && ((KnownOne2 & LowBits) != 0)) + KnownOne |= ~LowBits; + + KnownZero &= Mask; + KnownOne &= Mask; assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?"); } @@ -2755,13 +2765,16 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT, // EXTRACT_VECTOR_ELT of INSERT_VECTOR_ELT is often formed when vector // operations are lowered to scalars. if (N1.getOpcode() == ISD::INSERT_VECTOR_ELT) { - // If the indices are the same, return the inserted element. - if (N1.getOperand(2) == N2) - return N1.getOperand(1); - // If the indices are known different, extract the element from + // If the indices are the same, return the inserted element else + // if the indices are known different, extract the element from // the original vector. - else if (isa<ConstantSDNode>(N1.getOperand(2)) && - isa<ConstantSDNode>(N2)) + if (N1.getOperand(2) == N2) { + if (VT == N1.getOperand(1).getValueType()) + return N1.getOperand(1); + else + return getSExtOrTrunc(N1.getOperand(1), DL, VT); + } else if (isa<ConstantSDNode>(N1.getOperand(2)) && + isa<ConstantSDNode>(N2)) return getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, N1.getOperand(0), N2); } break; @@ -3287,7 +3300,7 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl, Value = getMemsetStringVal(VT, dl, DAG, TLI, Str, SrcOff); Store = DAG.getStore(Chain, dl, Value, getMemBasePlusOffset(Dst, DstOff, DAG), - DstSV, DstSVOff + DstOff, false, DstAlign); + DstSV, DstSVOff + DstOff, false, false, DstAlign); } else { // The type might not be legal for the target. This should only happen // if the type is smaller than a legal type, as on PPC, so the right @@ -3298,10 +3311,11 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl, assert(NVT.bitsGE(VT)); Value = DAG.getExtLoad(ISD::EXTLOAD, dl, NVT, Chain, getMemBasePlusOffset(Src, SrcOff, DAG), - SrcSV, SrcSVOff + SrcOff, VT, false, Align); + SrcSV, SrcSVOff + SrcOff, VT, false, false, Align); Store = DAG.getTruncStore(Chain, dl, Value, - getMemBasePlusOffset(Dst, DstOff, DAG), - DstSV, DstSVOff + DstOff, VT, false, DstAlign); + getMemBasePlusOffset(Dst, DstOff, DAG), + DstSV, DstSVOff + DstOff, VT, false, false, + DstAlign); } OutChains.push_back(Store); SrcOff += VTSize; @@ -3346,7 +3360,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl, Value = DAG.getLoad(VT, dl, Chain, getMemBasePlusOffset(Src, SrcOff, DAG), - SrcSV, SrcSVOff + SrcOff, false, Align); + SrcSV, SrcSVOff + SrcOff, false, false, Align); LoadValues.push_back(Value); LoadChains.push_back(Value.getValue(1)); SrcOff += VTSize; @@ -3361,7 +3375,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl, Store = DAG.getStore(Chain, dl, LoadValues[i], getMemBasePlusOffset(Dst, DstOff, DAG), - DstSV, DstSVOff + DstOff, false, DstAlign); + DstSV, DstSVOff + DstOff, false, false, DstAlign); OutChains.push_back(Store); DstOff += VTSize; } @@ -3396,7 +3410,7 @@ static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl, SDValue Value = getMemsetValue(Src, VT, DAG, dl); SDValue Store = DAG.getStore(Chain, dl, Value, getMemBasePlusOffset(Dst, DstOff, DAG), - DstSV, DstSVOff + DstOff); + DstSV, DstSVOff + DstOff, false, false, 0); OutChains.push_back(Store); DstOff += VTSize; } @@ -3776,7 +3790,8 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType, EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset, const Value *SV, int SVOffset, EVT MemVT, - bool isVolatile, unsigned Alignment) { + bool isVolatile, bool isNonTemporal, + unsigned Alignment) { if (Alignment == 0) // Ensure that codegen never sees alignment 0 Alignment = getEVTAlignment(VT); @@ -3790,6 +3805,8 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl, unsigned Flags = MachineMemOperand::MOLoad; if (isVolatile) Flags |= MachineMemOperand::MOVolatile; + if (isNonTemporal) + Flags |= MachineMemOperand::MONonTemporal; MachineMemOperand *MMO = MF.getMachineMemOperand(SV, Flags, SVOffset, MemVT.getStoreSize(), Alignment); @@ -3844,20 +3861,22 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl, SDValue SelectionDAG::getLoad(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr, const Value *SV, int SVOffset, - bool isVolatile, unsigned Alignment) { + bool isVolatile, bool isNonTemporal, + unsigned Alignment) { SDValue Undef = getUNDEF(Ptr.getValueType()); return getLoad(ISD::UNINDEXED, dl, ISD::NON_EXTLOAD, VT, Chain, Ptr, Undef, - SV, SVOffset, VT, isVolatile, Alignment); + SV, SVOffset, VT, isVolatile, isNonTemporal, Alignment); } SDValue SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT, SDValue Chain, SDValue Ptr, const Value *SV, int SVOffset, EVT MemVT, - bool isVolatile, unsigned Alignment) { + bool isVolatile, bool isNonTemporal, + unsigned Alignment) { SDValue Undef = getUNDEF(Ptr.getValueType()); return getLoad(ISD::UNINDEXED, dl, ExtType, VT, Chain, Ptr, Undef, - SV, SVOffset, MemVT, isVolatile, Alignment); + SV, SVOffset, MemVT, isVolatile, isNonTemporal, Alignment); } SDValue @@ -3869,12 +3888,13 @@ SelectionDAG::getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base, return getLoad(AM, dl, LD->getExtensionType(), OrigLoad.getValueType(), LD->getChain(), Base, Offset, LD->getSrcValue(), LD->getSrcValueOffset(), LD->getMemoryVT(), - LD->isVolatile(), LD->getAlignment()); + LD->isVolatile(), LD->isNonTemporal(), LD->getAlignment()); } SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, const Value *SV, int SVOffset, - bool isVolatile, unsigned Alignment) { + bool isVolatile, bool isNonTemporal, + unsigned Alignment) { if (Alignment == 0) // Ensure that codegen never sees alignment 0 Alignment = getEVTAlignment(Val.getValueType()); @@ -3888,6 +3908,8 @@ SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val, unsigned Flags = MachineMemOperand::MOStore; if (isVolatile) Flags |= MachineMemOperand::MOVolatile; + if (isNonTemporal) + Flags |= MachineMemOperand::MONonTemporal; MachineMemOperand *MMO = MF.getMachineMemOperand(SV, Flags, SVOffset, Val.getValueType().getStoreSize(), Alignment); @@ -3920,7 +3942,8 @@ SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue SelectionDAG::getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, const Value *SV, int SVOffset, EVT SVT, - bool isVolatile, unsigned Alignment) { + bool isVolatile, bool isNonTemporal, + unsigned Alignment) { if (Alignment == 0) // Ensure that codegen never sees alignment 0 Alignment = getEVTAlignment(SVT); @@ -3934,6 +3957,8 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, unsigned Flags = MachineMemOperand::MOStore; if (isVolatile) Flags |= MachineMemOperand::MOVolatile; + if (isNonTemporal) + Flags |= MachineMemOperand::MONonTemporal; MachineMemOperand *MMO = MF.getMachineMemOperand(SV, Flags, SVOffset, SVT.getStoreSize(), Alignment); @@ -4860,23 +4885,23 @@ SelectionDAG::getMachineNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, } /// getTargetExtractSubreg - A convenience function for creating -/// TargetInstrInfo::EXTRACT_SUBREG nodes. +/// TargetOpcode::EXTRACT_SUBREG nodes. SDValue SelectionDAG::getTargetExtractSubreg(int SRIdx, DebugLoc DL, EVT VT, SDValue Operand) { SDValue SRIdxVal = getTargetConstant(SRIdx, MVT::i32); - SDNode *Subreg = getMachineNode(TargetInstrInfo::EXTRACT_SUBREG, DL, + SDNode *Subreg = getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, VT, Operand, SRIdxVal); return SDValue(Subreg, 0); } /// getTargetInsertSubreg - A convenience function for creating -/// TargetInstrInfo::INSERT_SUBREG nodes. +/// TargetOpcode::INSERT_SUBREG nodes. SDValue SelectionDAG::getTargetInsertSubreg(int SRIdx, DebugLoc DL, EVT VT, SDValue Operand, SDValue Subreg) { SDValue SRIdxVal = getTargetConstant(SRIdx, MVT::i32); - SDNode *Result = getMachineNode(TargetInstrInfo::INSERT_SUBREG, DL, + SDNode *Result = getMachineNode(TargetOpcode::INSERT_SUBREG, DL, VT, Operand, Subreg, SRIdxVal); return SDValue(Result, 0); } @@ -5212,11 +5237,12 @@ unsigned SelectionDAG::AssignTopologicalOrder() { } } if (I == SortedPos) { - allnodes_iterator J = I; - SDNode *S = ++J; - dbgs() << "Offending node:\n"; +#ifndef NDEBUG + SDNode *S = ++I; + dbgs() << "Overran sorted position:\n"; S->dumprFull(); - assert(0 && "Overran sorted position"); +#endif + llvm_unreachable(0); } } @@ -5237,7 +5263,7 @@ unsigned SelectionDAG::AssignTopologicalOrder() { } /// AssignOrdering - Assign an order to the SDNode. -void SelectionDAG::AssignOrdering(SDNode *SD, unsigned Order) { +void SelectionDAG::AssignOrdering(const SDNode *SD, unsigned Order) { assert(SD && "Trying to assign an order to a null node!"); Ordering->add(SD, Order); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 23c7059a9b3a0..85ecb95e47523 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -131,6 +131,17 @@ namespace { } } + /// areValueTypesLegal - Return true if types of all the values are legal. + bool areValueTypesLegal() { + for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) { + EVT RegisterVT = RegVTs[Value]; + if (!TLI->isTypeLegal(RegisterVT)) + return false; + } + return true; + } + + /// append - Add the specified values to this one. void append(const RegsForValue &RHS) { TLI = RHS.TLI; @@ -176,7 +187,6 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order, assert(NumParts > 0 && "No parts to assemble!"); const TargetLowering &TLI = DAG.getTargetLoweringInfo(); SDValue Val = Parts[0]; - DAG.AssignOrdering(Val.getNode(), Order); if (NumParts > 1) { // Assemble the value from multiple parts. @@ -209,10 +219,6 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order, Val = DAG.getNode(ISD::BUILD_PAIR, dl, RoundVT, Lo, Hi); - DAG.AssignOrdering(Lo.getNode(), Order); - DAG.AssignOrdering(Hi.getNode(), Order); - DAG.AssignOrdering(Val.getNode(), Order); - if (RoundParts < NumParts) { // Assemble the trailing non-power-of-2 part. unsigned OddParts = NumParts - RoundParts; @@ -226,15 +232,11 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order, std::swap(Lo, Hi); EVT TotalVT = EVT::getIntegerVT(*DAG.getContext(), NumParts * PartBits); Hi = DAG.getNode(ISD::ANY_EXTEND, dl, TotalVT, Hi); - DAG.AssignOrdering(Hi.getNode(), Order); Hi = DAG.getNode(ISD::SHL, dl, TotalVT, Hi, DAG.getConstant(Lo.getValueType().getSizeInBits(), TLI.getPointerTy())); - DAG.AssignOrdering(Hi.getNode(), Order); Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, TotalVT, Lo); - DAG.AssignOrdering(Lo.getNode(), Order); Val = DAG.getNode(ISD::OR, dl, TotalVT, Lo, Hi); - DAG.AssignOrdering(Val.getNode(), Order); } } else if (ValueVT.isVector()) { // Handle a multi-element vector. @@ -275,7 +277,6 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order, Val = DAG.getNode(IntermediateVT.isVector() ? ISD::CONCAT_VECTORS : ISD::BUILD_VECTOR, dl, ValueVT, &Ops[0], NumIntermediates); - DAG.AssignOrdering(Val.getNode(), Order); } else if (PartVT.isFloatingPoint()) { // FP split into multiple FP parts (for ppcf128) assert(ValueVT == EVT(MVT::ppcf128) && PartVT == EVT(MVT::f64) && @@ -286,10 +287,6 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order, if (TLI.isBigEndian()) std::swap(Lo, Hi); Val = DAG.getNode(ISD::BUILD_PAIR, dl, ValueVT, Lo, Hi); - - DAG.AssignOrdering(Hi.getNode(), Order); - DAG.AssignOrdering(Lo.getNode(), Order); - DAG.AssignOrdering(Val.getNode(), Order); } else { // FP split into integer parts (soft fp) assert(ValueVT.isFloatingPoint() && PartVT.isInteger() && @@ -307,18 +304,14 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order, if (PartVT.isVector()) { assert(ValueVT.isVector() && "Unknown vector conversion!"); - SDValue Res = DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val); - DAG.AssignOrdering(Res.getNode(), Order); - return Res; + return DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val); } if (ValueVT.isVector()) { assert(ValueVT.getVectorElementType() == PartVT && ValueVT.getVectorNumElements() == 1 && "Only trivial scalar-to-vector conversions should get here!"); - SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, dl, ValueVT, Val); - DAG.AssignOrdering(Res.getNode(), Order); - return Res; + return DAG.getNode(ISD::BUILD_VECTOR, dl, ValueVT, Val); } if (PartVT.isInteger() && @@ -330,36 +323,24 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order, if (AssertOp != ISD::DELETED_NODE) Val = DAG.getNode(AssertOp, dl, PartVT, Val, DAG.getValueType(ValueVT)); - DAG.AssignOrdering(Val.getNode(), Order); - Val = DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val); - DAG.AssignOrdering(Val.getNode(), Order); - return Val; + return DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val); } else { - Val = DAG.getNode(ISD::ANY_EXTEND, dl, ValueVT, Val); - DAG.AssignOrdering(Val.getNode(), Order); - return Val; + return DAG.getNode(ISD::ANY_EXTEND, dl, ValueVT, Val); } } if (PartVT.isFloatingPoint() && ValueVT.isFloatingPoint()) { if (ValueVT.bitsLT(Val.getValueType())) { // FP_ROUND's are always exact here. - Val = DAG.getNode(ISD::FP_ROUND, dl, ValueVT, Val, - DAG.getIntPtrConstant(1)); - DAG.AssignOrdering(Val.getNode(), Order); - return Val; + return DAG.getNode(ISD::FP_ROUND, dl, ValueVT, Val, + DAG.getIntPtrConstant(1)); } - Val = DAG.getNode(ISD::FP_EXTEND, dl, ValueVT, Val); - DAG.AssignOrdering(Val.getNode(), Order); - return Val; + return DAG.getNode(ISD::FP_EXTEND, dl, ValueVT, Val); } - if (PartVT.getSizeInBits() == ValueVT.getSizeInBits()) { - Val = DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val); - DAG.AssignOrdering(Val.getNode(), Order); - return Val; - } + if (PartVT.getSizeInBits() == ValueVT.getSizeInBits()) + return DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val); llvm_unreachable("Unknown mismatch!"); return SDValue(); @@ -414,8 +395,6 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order, } } - DAG.AssignOrdering(Val.getNode(), Order); - // The value may have changed - recompute ValueVT. ValueVT = Val.getValueType(); assert(NumParts * PartBits == ValueVT.getSizeInBits() && @@ -448,9 +427,6 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order, NumParts = RoundParts; ValueVT = EVT::getIntegerVT(*DAG.getContext(), NumParts * PartBits); Val = DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val); - - DAG.AssignOrdering(OddVal.getNode(), Order); - DAG.AssignOrdering(Val.getNode(), Order); } // The number of parts is a power of 2. Repeatedly bisect the value using @@ -460,8 +436,6 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order, ValueVT.getSizeInBits()), Val); - DAG.AssignOrdering(Parts[0].getNode(), Order); - for (unsigned StepSize = NumParts; StepSize > 1; StepSize /= 2) { for (unsigned i = 0; i < NumParts; i += StepSize) { unsigned ThisBits = StepSize * PartBits / 2; @@ -476,16 +450,11 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order, ThisVT, Part0, DAG.getConstant(0, PtrVT)); - DAG.AssignOrdering(Part0.getNode(), Order); - DAG.AssignOrdering(Part1.getNode(), Order); - if (ThisBits == PartBits && ThisVT != PartVT) { Part0 = DAG.getNode(ISD::BIT_CONVERT, dl, PartVT, Part0); Part1 = DAG.getNode(ISD::BIT_CONVERT, dl, PartVT, Part1); - DAG.AssignOrdering(Part0.getNode(), Order); - DAG.AssignOrdering(Part1.getNode(), Order); } } } @@ -511,7 +480,6 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order, } } - DAG.AssignOrdering(Val.getNode(), Order); Parts[0] = Val; return; } @@ -539,8 +507,6 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order, Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, IntermediateVT, Val, DAG.getConstant(i, PtrVT)); - - DAG.AssignOrdering(Ops[i].getNode(), Order); } // Split the intermediate operands into legal parts. @@ -638,23 +604,34 @@ SDValue SelectionDAGBuilder::getControlRoot() { return Root; } +void SelectionDAGBuilder::AssignOrderingToNode(const SDNode *Node) { + if (DAG.GetOrdering(Node) != 0) return; // Already has ordering. + DAG.AssignOrdering(Node, SDNodeOrder); + + for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I) + AssignOrderingToNode(Node->getOperand(I).getNode()); +} + void SelectionDAGBuilder::visit(Instruction &I) { visit(I.getOpcode(), I); } void SelectionDAGBuilder::visit(unsigned Opcode, User &I) { - // We're processing a new instruction. - ++SDNodeOrder; - // Note: this doesn't use InstVisitor, because it has to work with // ConstantExpr's in addition to instructions. switch (Opcode) { default: llvm_unreachable("Unknown instruction type encountered!"); // Build the switch statement using the Instruction.def file. #define HANDLE_INST(NUM, OPCODE, CLASS) \ - case Instruction::OPCODE: return visit##OPCODE((CLASS&)I); + case Instruction::OPCODE: visit##OPCODE((CLASS&)I); break; #include "llvm/Instruction.def" } + + // Assign the ordering to the freshly created DAG nodes. + if (NodeMap.count(&I)) { + ++SDNodeOrder; + AssignOrderingToNode(getValue(&I).getNode()); + } } SDValue SelectionDAGBuilder::getValue(const Value *V) { @@ -699,10 +676,8 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) { Constants.push_back(SDValue(Val, i)); } - SDValue Res = DAG.getMergeValues(&Constants[0], Constants.size(), - getCurDebugLoc()); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); - return Res; + return DAG.getMergeValues(&Constants[0], Constants.size(), + getCurDebugLoc()); } if (isa<StructType>(C->getType()) || isa<ArrayType>(C->getType())) { @@ -725,10 +700,8 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) { Constants[i] = DAG.getConstant(0, EltVT); } - SDValue Res = DAG.getMergeValues(&Constants[0], NumElts, - getCurDebugLoc()); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); - return Res; + return DAG.getMergeValues(&Constants[0], NumElts, + getCurDebugLoc()); } if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) @@ -756,10 +729,8 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) { } // Create a BUILD_VECTOR node. - SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(), - VT, &Ops[0], Ops.size()); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); - return NodeMap[V] = Res; + return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(), + VT, &Ops[0], Ops.size()); } // If this is a static alloca, generate it as the frameindex instead of @@ -873,16 +844,11 @@ void SelectionDAGBuilder::visitRet(ReturnInst &I) { Chains[i] = DAG.getStore(Chain, getCurDebugLoc(), SDValue(RetOp.getNode(), RetOp.getResNo() + i), - Add, NULL, Offsets[i], false, 0); - - DAG.AssignOrdering(Add.getNode(), SDNodeOrder); - DAG.AssignOrdering(Chains[i].getNode(), SDNodeOrder); + Add, NULL, Offsets[i], false, false, 0); } Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other, &Chains[0], NumValues); - - DAG.AssignOrdering(Chain.getNode(), SDNodeOrder); } else { for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { SmallVector<EVT, 4> ValueVTs; @@ -948,7 +914,6 @@ void SelectionDAGBuilder::visitRet(ReturnInst &I) { // Update the DAG with the new chain value resulting from return lowering. DAG.setRoot(Chain); - DAG.AssignOrdering(Chain.getNode(), SDNodeOrder); } /// CopyToExportRegsIfNeeded - If the given value has virtual registers @@ -1209,13 +1174,10 @@ void SelectionDAGBuilder::visitBr(BranchInst &I) { CurMBB->addSuccessor(Succ0MBB); // If this is not a fall-through branch, emit the branch. - if (Succ0MBB != NextBlock) { - SDValue V = DAG.getNode(ISD::BR, getCurDebugLoc(), + if (Succ0MBB != NextBlock) + DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, getControlRoot(), - DAG.getBasicBlock(Succ0MBB)); - DAG.setRoot(V); - DAG.AssignOrdering(V.getNode(), SDNodeOrder); - } + DAG.getBasicBlock(Succ0MBB))); return; } @@ -1321,8 +1283,6 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB) { } } - DAG.AssignOrdering(Cond.getNode(), SDNodeOrder); - // Update successor info CurMBB->addSuccessor(CB.TrueBB); CurMBB->addSuccessor(CB.FalseBB); @@ -1340,13 +1300,11 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB) { std::swap(CB.TrueBB, CB.FalseBB); SDValue True = DAG.getConstant(1, Cond.getValueType()); Cond = DAG.getNode(ISD::XOR, dl, Cond.getValueType(), Cond, True); - DAG.AssignOrdering(Cond.getNode(), SDNodeOrder); } SDValue BrCond = DAG.getNode(ISD::BRCOND, dl, MVT::Other, getControlRoot(), Cond, DAG.getBasicBlock(CB.TrueBB)); - DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder); // If the branch was constant folded, fix up the CFG. if (BrCond.getOpcode() == ISD::BR) { @@ -1356,12 +1314,9 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB) { if (BrCond == getControlRoot()) CurMBB->removeSuccessor(CB.TrueBB); - if (CB.FalseBB != NextBlock) { + if (CB.FalseBB != NextBlock) BrCond = DAG.getNode(ISD::BR, dl, MVT::Other, BrCond, DAG.getBasicBlock(CB.FalseBB)); - - DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder); - } } DAG.setRoot(BrCond); @@ -1379,10 +1334,6 @@ void SelectionDAGBuilder::visitJumpTable(JumpTable &JT) { MVT::Other, Index.getValue(1), Table, Index); DAG.setRoot(BrJumpTable); - - DAG.AssignOrdering(Index.getNode(), SDNodeOrder); - DAG.AssignOrdering(Table.getNode(), SDNodeOrder); - DAG.AssignOrdering(BrJumpTable.getNode(), SDNodeOrder); } /// visitJumpTableHeader - This function emits necessary code to produce index @@ -1398,7 +1349,7 @@ void SelectionDAGBuilder::visitJumpTableHeader(JumpTable &JT, DAG.getConstant(JTH.First, VT)); // The SDNode we just created, which holds the value being switched on minus - // the the smallest case value, needs to be copied to a virtual register so it + // the smallest case value, needs to be copied to a virtual register so it // can be used as an index into the jump table in a subsequent basic block. // This value may be smaller or larger than the target's pointer type, and // therefore require extension or truncating. @@ -1417,11 +1368,6 @@ void SelectionDAGBuilder::visitJumpTableHeader(JumpTable &JT, DAG.getConstant(JTH.Last-JTH.First,VT), ISD::SETUGT); - DAG.AssignOrdering(Sub.getNode(), SDNodeOrder); - DAG.AssignOrdering(SwitchOp.getNode(), SDNodeOrder); - DAG.AssignOrdering(CopyTo.getNode(), SDNodeOrder); - DAG.AssignOrdering(CMP.getNode(), SDNodeOrder); - // Set NextBlock to be the MBB immediately after the current one, if any. // This is used to avoid emitting unnecessary branches to the next block. MachineBasicBlock *NextBlock = 0; @@ -1434,13 +1380,9 @@ void SelectionDAGBuilder::visitJumpTableHeader(JumpTable &JT, MVT::Other, CopyTo, CMP, DAG.getBasicBlock(JT.Default)); - DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder); - - if (JT.MBB != NextBlock) { + if (JT.MBB != NextBlock) BrCond = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrCond, DAG.getBasicBlock(JT.MBB)); - DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder); - } DAG.setRoot(BrCond); } @@ -1467,11 +1409,6 @@ void SelectionDAGBuilder::visitBitTestHeader(BitTestBlock &B) { SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), getCurDebugLoc(), B.Reg, ShiftOp); - DAG.AssignOrdering(Sub.getNode(), SDNodeOrder); - DAG.AssignOrdering(RangeCmp.getNode(), SDNodeOrder); - DAG.AssignOrdering(ShiftOp.getNode(), SDNodeOrder); - DAG.AssignOrdering(CopyTo.getNode(), SDNodeOrder); - // Set NextBlock to be the MBB immediately after the current one, if any. // This is used to avoid emitting unnecessary branches to the next block. MachineBasicBlock *NextBlock = 0; @@ -1488,13 +1425,9 @@ void SelectionDAGBuilder::visitBitTestHeader(BitTestBlock &B) { MVT::Other, CopyTo, RangeCmp, DAG.getBasicBlock(B.Default)); - DAG.AssignOrdering(BrRange.getNode(), SDNodeOrder); - - if (MBB != NextBlock) { + if (MBB != NextBlock) BrRange = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, CopyTo, DAG.getBasicBlock(MBB)); - DAG.AssignOrdering(BrRange.getNode(), SDNodeOrder); - } DAG.setRoot(BrRange); } @@ -1520,11 +1453,6 @@ void SelectionDAGBuilder::visitBitTestCase(MachineBasicBlock* NextMBB, AndOp, DAG.getConstant(0, TLI.getPointerTy()), ISD::SETNE); - DAG.AssignOrdering(ShiftOp.getNode(), SDNodeOrder); - DAG.AssignOrdering(SwitchVal.getNode(), SDNodeOrder); - DAG.AssignOrdering(AndOp.getNode(), SDNodeOrder); - DAG.AssignOrdering(AndCmp.getNode(), SDNodeOrder); - CurMBB->addSuccessor(B.TargetBB); CurMBB->addSuccessor(NextMBB); @@ -1532,8 +1460,6 @@ void SelectionDAGBuilder::visitBitTestCase(MachineBasicBlock* NextMBB, MVT::Other, getControlRoot(), AndCmp, DAG.getBasicBlock(B.TargetBB)); - DAG.AssignOrdering(BrAnd.getNode(), SDNodeOrder); - // Set NextBlock to be the MBB immediately after the current one, if any. // This is used to avoid emitting unnecessary branches to the next block. MachineBasicBlock *NextBlock = 0; @@ -1541,11 +1467,9 @@ void SelectionDAGBuilder::visitBitTestCase(MachineBasicBlock* NextMBB, if (++BBI != FuncInfo.MF->end()) NextBlock = BBI; - if (NextMBB != NextBlock) { + if (NextMBB != NextBlock) BrAnd = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrAnd, DAG.getBasicBlock(NextMBB)); - DAG.AssignOrdering(BrAnd.getNode(), SDNodeOrder); - } DAG.setRoot(BrAnd); } @@ -1570,11 +1494,9 @@ void SelectionDAGBuilder::visitInvoke(InvokeInst &I) { CurMBB->addSuccessor(LandingPad); // Drop into normal successor. - SDValue Branch = DAG.getNode(ISD::BR, getCurDebugLoc(), - MVT::Other, getControlRoot(), - DAG.getBasicBlock(Return)); - DAG.setRoot(Branch); - DAG.AssignOrdering(Branch.getNode(), SDNodeOrder); + DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), + MVT::Other, getControlRoot(), + DAG.getBasicBlock(Return))); } void SelectionDAGBuilder::visitUnwind(UnwindInst &I) { @@ -1733,8 +1655,8 @@ bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec& CR, std::vector<MachineBasicBlock*> DestBBs; APInt TEI = First; for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++TEI) { - const APInt& Low = cast<ConstantInt>(I->Low)->getValue(); - const APInt& High = cast<ConstantInt>(I->High)->getValue(); + const APInt &Low = cast<ConstantInt>(I->Low)->getValue(); + const APInt &High = cast<ConstantInt>(I->High)->getValue(); if (Low.sle(TEI) && TEI.sle(High)) { DestBBs.push_back(I->BB); @@ -1757,7 +1679,9 @@ bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec& CR, // Create a jump table index for this jump table, or return an existing // one. - unsigned JTI = CurMF->getJumpTableInfo()->getJumpTableIndex(DestBBs); + unsigned JTEncoding = TLI.getJumpTableEncoding(); + unsigned JTI = CurMF->getOrCreateJumpTableInfo(JTEncoding) + ->getJumpTableIndex(DestBBs); // Set the jump table information so that we can codegen it as a second // MachineBasicBlock @@ -2086,13 +2010,10 @@ void SelectionDAGBuilder::visitSwitch(SwitchInst &SI) { // If this is not a fall-through branch, emit the branch. CurMBB->addSuccessor(Default); - if (Default != NextBlock) { - SDValue Res = DAG.getNode(ISD::BR, getCurDebugLoc(), - MVT::Other, getControlRoot(), - DAG.getBasicBlock(Default)); - DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); - } + if (Default != NextBlock) + DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), + MVT::Other, getControlRoot(), + DAG.getBasicBlock(Default))); return; } @@ -2141,15 +2062,19 @@ void SelectionDAGBuilder::visitSwitch(SwitchInst &SI) { } void SelectionDAGBuilder::visitIndirectBr(IndirectBrInst &I) { - // Update machine-CFG edges. + // Update machine-CFG edges with unique successors. + SmallVector<BasicBlock*, 32> succs; + succs.reserve(I.getNumSuccessors()); for (unsigned i = 0, e = I.getNumSuccessors(); i != e; ++i) - CurMBB->addSuccessor(FuncInfo.MBBMap[I.getSuccessor(i)]); - - SDValue Res = DAG.getNode(ISD::BRIND, getCurDebugLoc(), - MVT::Other, getControlRoot(), - getValue(I.getAddress())); - DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + succs.push_back(I.getSuccessor(i)); + array_pod_sort(succs.begin(), succs.end()); + succs.erase(std::unique(succs.begin(), succs.end()), succs.end()); + for (unsigned i = 0, e = succs.size(); i != e; ++i) + CurMBB->addSuccessor(FuncInfo.MBBMap[succs[i]]); + + DAG.setRoot(DAG.getNode(ISD::BRIND, getCurDebugLoc(), + MVT::Other, getControlRoot(), + getValue(I.getAddress()))); } void SelectionDAGBuilder::visitFSub(User &I) { @@ -2164,10 +2089,8 @@ void SelectionDAGBuilder::visitFSub(User &I) { Constant *CNZ = ConstantVector::get(&NZ[0], NZ.size()); if (CV == CNZ) { SDValue Op2 = getValue(I.getOperand(1)); - SDValue Res = DAG.getNode(ISD::FNEG, getCurDebugLoc(), - Op2.getValueType(), Op2); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::FNEG, getCurDebugLoc(), + Op2.getValueType(), Op2)); return; } } @@ -2176,10 +2099,8 @@ void SelectionDAGBuilder::visitFSub(User &I) { if (ConstantFP *CFP = dyn_cast<ConstantFP>(I.getOperand(0))) if (CFP->isExactlyValue(ConstantFP::getNegativeZero(Ty)->getValueAPF())) { SDValue Op2 = getValue(I.getOperand(1)); - SDValue Res = DAG.getNode(ISD::FNEG, getCurDebugLoc(), - Op2.getValueType(), Op2); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::FNEG, getCurDebugLoc(), + Op2.getValueType(), Op2)); return; } @@ -2189,10 +2110,8 @@ void SelectionDAGBuilder::visitFSub(User &I) { void SelectionDAGBuilder::visitBinary(User &I, unsigned OpCode) { SDValue Op1 = getValue(I.getOperand(0)); SDValue Op2 = getValue(I.getOperand(1)); - SDValue Res = DAG.getNode(OpCode, getCurDebugLoc(), - Op1.getValueType(), Op1, Op2); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(OpCode, getCurDebugLoc(), + Op1.getValueType(), Op1, Op2)); } void SelectionDAGBuilder::visitShift(User &I, unsigned Opcode) { @@ -2225,12 +2144,8 @@ void SelectionDAGBuilder::visitShift(User &I, unsigned Opcode) { TLI.getPointerTy(), Op2); } - SDValue Res = DAG.getNode(Opcode, getCurDebugLoc(), - Op1.getValueType(), Op1, Op2); - setValue(&I, Res); - DAG.AssignOrdering(Op1.getNode(), SDNodeOrder); - DAG.AssignOrdering(Op2.getNode(), SDNodeOrder); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(Opcode, getCurDebugLoc(), + Op1.getValueType(), Op1, Op2)); } void SelectionDAGBuilder::visitICmp(User &I) { @@ -2244,9 +2159,7 @@ void SelectionDAGBuilder::visitICmp(User &I) { ISD::CondCode Opcode = getICmpCondCode(predicate); EVT DestVT = TLI.getValueType(I.getType()); - SDValue Res = DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Opcode); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Opcode)); } void SelectionDAGBuilder::visitFCmp(User &I) { @@ -2259,9 +2172,7 @@ void SelectionDAGBuilder::visitFCmp(User &I) { SDValue Op2 = getValue(I.getOperand(1)); ISD::CondCode Condition = getFCmpCondCode(predicate); EVT DestVT = TLI.getValueType(I.getType()); - SDValue Res = DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Condition); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Condition)); } void SelectionDAGBuilder::visitSelect(User &I) { @@ -2275,7 +2186,7 @@ void SelectionDAGBuilder::visitSelect(User &I) { SDValue TrueVal = getValue(I.getOperand(1)); SDValue FalseVal = getValue(I.getOperand(2)); - for (unsigned i = 0; i != NumValues; ++i) { + for (unsigned i = 0; i != NumValues; ++i) Values[i] = DAG.getNode(ISD::SELECT, getCurDebugLoc(), TrueVal.getNode()->getValueType(i), Cond, SDValue(TrueVal.getNode(), @@ -2283,23 +2194,16 @@ void SelectionDAGBuilder::visitSelect(User &I) { SDValue(FalseVal.getNode(), FalseVal.getResNo() + i)); - DAG.AssignOrdering(Values[i].getNode(), SDNodeOrder); - } - - SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), - DAG.getVTList(&ValueVTs[0], NumValues), - &Values[0], NumValues); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), + DAG.getVTList(&ValueVTs[0], NumValues), + &Values[0], NumValues)); } void SelectionDAGBuilder::visitTrunc(User &I) { // TruncInst cannot be a no-op cast because sizeof(src) > sizeof(dest). SDValue N = getValue(I.getOperand(0)); EVT DestVT = TLI.getValueType(I.getType()); - SDValue Res = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), DestVT, N); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), DestVT, N)); } void SelectionDAGBuilder::visitZExt(User &I) { @@ -2307,9 +2211,7 @@ void SelectionDAGBuilder::visitZExt(User &I) { // ZExt also can't be a cast to bool for same reason. So, nothing much to do SDValue N = getValue(I.getOperand(0)); EVT DestVT = TLI.getValueType(I.getType()); - SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), DestVT, N); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), DestVT, N)); } void SelectionDAGBuilder::visitSExt(User &I) { @@ -2317,64 +2219,50 @@ void SelectionDAGBuilder::visitSExt(User &I) { // SExt also can't be a cast to bool for same reason. So, nothing much to do SDValue N = getValue(I.getOperand(0)); EVT DestVT = TLI.getValueType(I.getType()); - SDValue Res = DAG.getNode(ISD::SIGN_EXTEND, getCurDebugLoc(), DestVT, N); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, getCurDebugLoc(), DestVT, N)); } void SelectionDAGBuilder::visitFPTrunc(User &I) { // FPTrunc is never a no-op cast, no need to check SDValue N = getValue(I.getOperand(0)); EVT DestVT = TLI.getValueType(I.getType()); - SDValue Res = DAG.getNode(ISD::FP_ROUND, getCurDebugLoc(), - DestVT, N, DAG.getIntPtrConstant(0)); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::FP_ROUND, getCurDebugLoc(), + DestVT, N, DAG.getIntPtrConstant(0))); } void SelectionDAGBuilder::visitFPExt(User &I){ // FPTrunc is never a no-op cast, no need to check SDValue N = getValue(I.getOperand(0)); EVT DestVT = TLI.getValueType(I.getType()); - SDValue Res = DAG.getNode(ISD::FP_EXTEND, getCurDebugLoc(), DestVT, N); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::FP_EXTEND, getCurDebugLoc(), DestVT, N)); } void SelectionDAGBuilder::visitFPToUI(User &I) { // FPToUI is never a no-op cast, no need to check SDValue N = getValue(I.getOperand(0)); EVT DestVT = TLI.getValueType(I.getType()); - SDValue Res = DAG.getNode(ISD::FP_TO_UINT, getCurDebugLoc(), DestVT, N); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::FP_TO_UINT, getCurDebugLoc(), DestVT, N)); } void SelectionDAGBuilder::visitFPToSI(User &I) { // FPToSI is never a no-op cast, no need to check SDValue N = getValue(I.getOperand(0)); EVT DestVT = TLI.getValueType(I.getType()); - SDValue Res = DAG.getNode(ISD::FP_TO_SINT, getCurDebugLoc(), DestVT, N); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::FP_TO_SINT, getCurDebugLoc(), DestVT, N)); } void SelectionDAGBuilder::visitUIToFP(User &I) { // UIToFP is never a no-op cast, no need to check SDValue N = getValue(I.getOperand(0)); EVT DestVT = TLI.getValueType(I.getType()); - SDValue Res = DAG.getNode(ISD::UINT_TO_FP, getCurDebugLoc(), DestVT, N); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::UINT_TO_FP, getCurDebugLoc(), DestVT, N)); } void SelectionDAGBuilder::visitSIToFP(User &I){ // SIToFP is never a no-op cast, no need to check SDValue N = getValue(I.getOperand(0)); EVT DestVT = TLI.getValueType(I.getType()); - SDValue Res = DAG.getNode(ISD::SINT_TO_FP, getCurDebugLoc(), DestVT, N); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::SINT_TO_FP, getCurDebugLoc(), DestVT, N)); } void SelectionDAGBuilder::visitPtrToInt(User &I) { @@ -2383,9 +2271,7 @@ void SelectionDAGBuilder::visitPtrToInt(User &I) { SDValue N = getValue(I.getOperand(0)); EVT SrcVT = N.getValueType(); EVT DestVT = TLI.getValueType(I.getType()); - SDValue Res = DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT)); } void SelectionDAGBuilder::visitIntToPtr(User &I) { @@ -2394,9 +2280,7 @@ void SelectionDAGBuilder::visitIntToPtr(User &I) { SDValue N = getValue(I.getOperand(0)); EVT SrcVT = N.getValueType(); EVT DestVT = TLI.getValueType(I.getType()); - SDValue Res = DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT)); } void SelectionDAGBuilder::visitBitCast(User &I) { @@ -2405,14 +2289,11 @@ void SelectionDAGBuilder::visitBitCast(User &I) { // BitCast assures us that source and destination are the same size so this is // either a BIT_CONVERT or a no-op. - if (DestVT != N.getValueType()) { - SDValue Res = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), - DestVT, N); // convert types. - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); - } else { + if (DestVT != N.getValueType()) + setValue(&I, DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), + DestVT, N)); // convert types. + else setValue(&I, N); // noop cast. - } } void SelectionDAGBuilder::visitInsertElement(User &I) { @@ -2421,13 +2302,9 @@ void SelectionDAGBuilder::visitInsertElement(User &I) { SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), TLI.getPointerTy(), getValue(I.getOperand(2))); - SDValue Res = DAG.getNode(ISD::INSERT_VECTOR_ELT, getCurDebugLoc(), - TLI.getValueType(I.getType()), - InVec, InVal, InIdx); - setValue(&I, Res); - - DAG.AssignOrdering(InIdx.getNode(), SDNodeOrder); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::INSERT_VECTOR_ELT, getCurDebugLoc(), + TLI.getValueType(I.getType()), + InVec, InVal, InIdx)); } void SelectionDAGBuilder::visitExtractElement(User &I) { @@ -2435,15 +2312,10 @@ void SelectionDAGBuilder::visitExtractElement(User &I) { SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), TLI.getPointerTy(), getValue(I.getOperand(1))); - SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(), - TLI.getValueType(I.getType()), InVec, InIdx); - setValue(&I, Res); - - DAG.AssignOrdering(InIdx.getNode(), SDNodeOrder); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(), + TLI.getValueType(I.getType()), InVec, InIdx)); } - // Utility for visitShuffleVector - Returns true if the mask is mask starting // from SIndx and increasing to the element length (undefs are allowed). static bool SequentialMask(SmallVectorImpl<int> &Mask, unsigned SIndx) { @@ -2462,8 +2334,7 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) { // Convert the ConstantVector mask operand into an array of ints, with -1 // representing undef values. SmallVector<Constant*, 8> MaskElts; - cast<Constant>(I.getOperand(2))->getVectorElements(*DAG.getContext(), - MaskElts); + cast<Constant>(I.getOperand(2))->getVectorElements(MaskElts); unsigned MaskNumElts = MaskElts.size(); for (unsigned i = 0; i != MaskNumElts; ++i) { if (isa<UndefValue>(MaskElts[i])) @@ -2477,10 +2348,8 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) { unsigned SrcNumElts = SrcVT.getVectorNumElements(); if (SrcNumElts == MaskNumElts) { - SDValue Res = DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2, - &Mask[0]); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2, + &Mask[0])); return; } @@ -2491,10 +2360,8 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) { // lengths match. if (SrcNumElts*2 == MaskNumElts && SequentialMask(Mask, 0)) { // The shuffle is concatenating two vectors together. - SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, getCurDebugLoc(), - VT, Src1, Src2); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, getCurDebugLoc(), + VT, Src1, Src2)); return; } @@ -2526,12 +2393,8 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) { MappedOps.push_back(Idx + MaskNumElts - SrcNumElts); } - SDValue Res = DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2, - &MappedOps[0]); - setValue(&I, Res); - DAG.AssignOrdering(Src1.getNode(), SDNodeOrder); - DAG.AssignOrdering(Src2.getNode(), SDNodeOrder); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2, + &MappedOps[0])); return; } @@ -2583,9 +2446,7 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) { } if (RangeUse[0] == 0 && RangeUse[1] == 0) { - SDValue Res = DAG.getUNDEF(VT); - setValue(&I, Res); // Vectors are not used. - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getUNDEF(VT)); // Vectors are not used. return; } else if (RangeUse[0] < 2 && RangeUse[1] < 2) { @@ -2597,8 +2458,6 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) { else Src = DAG.getNode(ISD::EXTRACT_SUBVECTOR, getCurDebugLoc(), VT, Src, DAG.getIntPtrConstant(StartIdx[Input])); - - DAG.AssignOrdering(Src.getNode(), SDNodeOrder); } // Calculate new mask. @@ -2613,10 +2472,8 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) { MappedOps.push_back(Idx - SrcNumElts - StartIdx[1] + MaskNumElts); } - SDValue Res = DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2, - &MappedOps[0]); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2, + &MappedOps[0])); return; } } @@ -2643,14 +2500,11 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) { DAG.getConstant(Idx - SrcNumElts, PtrVT)); Ops.push_back(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); } } - SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(), - VT, &Ops[0], Ops.size()); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(), + VT, &Ops[0], Ops.size())); } void SelectionDAGBuilder::visitInsertValue(InsertValueInst &I) { @@ -2689,11 +2543,9 @@ void SelectionDAGBuilder::visitInsertValue(InsertValueInst &I) { Values[i] = IntoUndef ? DAG.getUNDEF(AggValueVTs[i]) : SDValue(Agg.getNode(), Agg.getResNo() + i); - SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), - DAG.getVTList(&AggValueVTs[0], NumAggValues), - &Values[0], NumAggValues); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), + DAG.getVTList(&AggValueVTs[0], NumAggValues), + &Values[0], NumAggValues)); } void SelectionDAGBuilder::visitExtractValue(ExtractValueInst &I) { @@ -2719,11 +2571,9 @@ void SelectionDAGBuilder::visitExtractValue(ExtractValueInst &I) { DAG.getUNDEF(Agg.getNode()->getValueType(Agg.getResNo() + i)) : SDValue(Agg.getNode(), Agg.getResNo() + i); - SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), - DAG.getVTList(&ValValueVTs[0], NumValValues), - &Values[0], NumValValues); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), + DAG.getVTList(&ValValueVTs[0], NumValValues), + &Values[0], NumValValues)); } void SelectionDAGBuilder::visitGetElementPtr(User &I) { @@ -2740,7 +2590,6 @@ void SelectionDAGBuilder::visitGetElementPtr(User &I) { uint64_t Offset = TD->getStructLayout(StTy)->getElementOffset(Field); N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N, DAG.getIntPtrConstant(Offset)); - DAG.AssignOrdering(N.getNode(), SDNodeOrder); } Ty = StTy->getElementType(Field); @@ -2764,9 +2613,6 @@ void SelectionDAGBuilder::visitGetElementPtr(User &I) { N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N, OffsVal); - - DAG.AssignOrdering(OffsVal.getNode(), SDNodeOrder); - DAG.AssignOrdering(N.getNode(), SDNodeOrder); continue; } @@ -2792,13 +2638,10 @@ void SelectionDAGBuilder::visitGetElementPtr(User &I) { IdxN = DAG.getNode(ISD::MUL, getCurDebugLoc(), N.getValueType(), IdxN, Scale); } - - DAG.AssignOrdering(IdxN.getNode(), SDNodeOrder); } N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N, IdxN); - DAG.AssignOrdering(N.getNode(), SDNodeOrder); } } @@ -2823,11 +2666,8 @@ void SelectionDAGBuilder::visitAlloca(AllocaInst &I) { AllocSize, DAG.getConstant(TySize, AllocSize.getValueType())); - DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder); - EVT IntPtr = TLI.getPointerTy(); AllocSize = DAG.getZExtOrTrunc(AllocSize, getCurDebugLoc(), IntPtr); - DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder); // Handle alignment. If the requested alignment is less than or equal to // the stack alignment, ignore it. If the size is greater than or equal to @@ -2842,13 +2682,11 @@ void SelectionDAGBuilder::visitAlloca(AllocaInst &I) { AllocSize = DAG.getNode(ISD::ADD, getCurDebugLoc(), AllocSize.getValueType(), AllocSize, DAG.getIntPtrConstant(StackAlign-1)); - DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder); // Mask out the low bits for alignment purposes. AllocSize = DAG.getNode(ISD::AND, getCurDebugLoc(), AllocSize.getValueType(), AllocSize, DAG.getIntPtrConstant(~(uint64_t)(StackAlign-1))); - DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder); SDValue Ops[] = { getRoot(), AllocSize, DAG.getIntPtrConstant(Align) }; SDVTList VTs = DAG.getVTList(AllocSize.getValueType(), MVT::Other); @@ -2856,7 +2694,6 @@ void SelectionDAGBuilder::visitAlloca(AllocaInst &I) { VTs, Ops, 3); setValue(&I, DSA); DAG.setRoot(DSA.getValue(1)); - DAG.AssignOrdering(DSA.getNode(), SDNodeOrder); // Inform the Frame Information that we have just allocated a variable-sized // object. @@ -2868,7 +2705,9 @@ void SelectionDAGBuilder::visitLoad(LoadInst &I) { SDValue Ptr = getValue(SV); const Type *Ty = I.getType(); + bool isVolatile = I.isVolatile(); + bool isNonTemporal = I.getMetadata("nontemporal") != 0; unsigned Alignment = I.getAlignment(); SmallVector<EVT, 4> ValueVTs; @@ -2900,13 +2739,11 @@ void SelectionDAGBuilder::visitLoad(LoadInst &I) { PtrVT, Ptr, DAG.getConstant(Offsets[i], PtrVT)); SDValue L = DAG.getLoad(ValueVTs[i], getCurDebugLoc(), Root, - A, SV, Offsets[i], isVolatile, Alignment); + A, SV, Offsets[i], isVolatile, + isNonTemporal, Alignment); Values[i] = L; Chains[i] = L.getValue(1); - - DAG.AssignOrdering(A.getNode(), SDNodeOrder); - DAG.AssignOrdering(L.getNode(), SDNodeOrder); } if (!ConstantMemory) { @@ -2916,15 +2753,11 @@ void SelectionDAGBuilder::visitLoad(LoadInst &I) { DAG.setRoot(Chain); else PendingLoads.push_back(Chain); - - DAG.AssignOrdering(Chain.getNode(), SDNodeOrder); } - SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), - DAG.getVTList(&ValueVTs[0], NumValues), - &Values[0], NumValues); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), + DAG.getVTList(&ValueVTs[0], NumValues), + &Values[0], NumValues)); } void SelectionDAGBuilder::visitStore(StoreInst &I) { @@ -2948,6 +2781,7 @@ void SelectionDAGBuilder::visitStore(StoreInst &I) { SmallVector<SDValue, 4> Chains(NumValues); EVT PtrVT = Ptr.getValueType(); bool isVolatile = I.isVolatile(); + bool isNonTemporal = I.getMetadata("nontemporal") != 0; unsigned Alignment = I.getAlignment(); for (unsigned i = 0; i != NumValues; ++i) { @@ -2955,16 +2789,12 @@ void SelectionDAGBuilder::visitStore(StoreInst &I) { DAG.getConstant(Offsets[i], PtrVT)); Chains[i] = DAG.getStore(Root, getCurDebugLoc(), SDValue(Src.getNode(), Src.getResNo() + i), - Add, PtrV, Offsets[i], isVolatile, Alignment); - - DAG.AssignOrdering(Add.getNode(), SDNodeOrder); - DAG.AssignOrdering(Chains[i].getNode(), SDNodeOrder); + Add, PtrV, Offsets[i], isVolatile, + isNonTemporal, Alignment); } - SDValue Res = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), - MVT::Other, &Chains[0], NumValues); - DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + DAG.setRoot(DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), + MVT::Other, &Chains[0], NumValues)); } /// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC @@ -3035,8 +2865,6 @@ void SelectionDAGBuilder::visitTargetIntrinsic(CallInst &I, VTs, &Ops[0], Ops.size()); } - DAG.AssignOrdering(Result.getNode(), SDNodeOrder); - if (HasChain) { SDValue Chain = Result.getValue(Result.getNode()->getNumValues()-1); if (OnlyLoad) @@ -3049,7 +2877,6 @@ void SelectionDAGBuilder::visitTargetIntrinsic(CallInst &I, if (const VectorType *PTy = dyn_cast<VectorType>(I.getType())) { EVT VT = TLI.getValueType(PTy); Result = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), VT, Result); - DAG.AssignOrdering(Result.getNode(), SDNodeOrder); } setValue(&I, Result); @@ -3068,12 +2895,7 @@ GetSignificand(SelectionDAG &DAG, SDValue Op, DebugLoc dl, unsigned Order) { DAG.getConstant(0x007fffff, MVT::i32)); SDValue t2 = DAG.getNode(ISD::OR, dl, MVT::i32, t1, DAG.getConstant(0x3f800000, MVT::i32)); - SDValue Res = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t2); - - DAG.AssignOrdering(t1.getNode(), Order); - DAG.AssignOrdering(t2.getNode(), Order); - DAG.AssignOrdering(Res.getNode(), Order); - return Res; + return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t2); } /// GetExponent - Get the exponent: @@ -3090,13 +2912,7 @@ GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI, DAG.getConstant(23, TLI.getPointerTy())); SDValue t2 = DAG.getNode(ISD::SUB, dl, MVT::i32, t1, DAG.getConstant(127, MVT::i32)); - SDValue Res = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, t2); - - DAG.AssignOrdering(t0.getNode(), Order); - DAG.AssignOrdering(t1.getNode(), Order); - DAG.AssignOrdering(t2.getNode(), Order); - DAG.AssignOrdering(Res.getNode(), Order); - return Res; + return DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, t2); } /// getF32Constant - Get 32-bit floating point constant. @@ -3120,7 +2936,6 @@ SelectionDAGBuilder::implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op) { I.getOperand(1)); setValue(&I, L); DAG.setRoot(L.getValue(1)); - DAG.AssignOrdering(L.getNode(), SDNodeOrder); return 0; } @@ -3131,10 +2946,7 @@ SelectionDAGBuilder::implVisitAluOverflow(CallInst &I, ISD::NodeType Op) { SDValue Op2 = getValue(I.getOperand(2)); SDVTList VTs = DAG.getVTList(Op1.getValueType(), MVT::i1); - SDValue Result = DAG.getNode(Op, getCurDebugLoc(), VTs, Op1, Op2); - - setValue(&I, Result); - DAG.AssignOrdering(Result.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(Op, getCurDebugLoc(), VTs, Op1, Op2)); return 0; } @@ -3162,15 +2974,9 @@ SelectionDAGBuilder::visitExp(CallInst &I) { SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX); SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0, t1); - DAG.AssignOrdering(t0.getNode(), SDNodeOrder); - DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder); - DAG.AssignOrdering(t1.getNode(), SDNodeOrder); - DAG.AssignOrdering(X.getNode(), SDNodeOrder); - // IntegerPartOfX <<= 23; IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX, DAG.getConstant(23, TLI.getPointerTy())); - DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder); if (LimitFloatPrecision <= 6) { // For floating-point precision of 6: @@ -3194,14 +3000,6 @@ SelectionDAGBuilder::visitExp(CallInst &I) { TwoToFracPartOfX, IntegerPartOfX); result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t6); - - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(TwoToFracPartOfX.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) { // For floating-point precision of 12: // @@ -3228,16 +3026,6 @@ SelectionDAGBuilder::visitExp(CallInst &I) { TwoToFracPartOfX, IntegerPartOfX); result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t8); - - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(t7.getNode(), SDNodeOrder); - DAG.AssignOrdering(t8.getNode(), SDNodeOrder); - DAG.AssignOrdering(TwoToFracPartOfX.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18 // For floating-point precision of 18: // @@ -3277,29 +3065,12 @@ SelectionDAGBuilder::visitExp(CallInst &I) { TwoToFracPartOfX, IntegerPartOfX); result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t14); - - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(t7.getNode(), SDNodeOrder); - DAG.AssignOrdering(t8.getNode(), SDNodeOrder); - DAG.AssignOrdering(t9.getNode(), SDNodeOrder); - DAG.AssignOrdering(t10.getNode(), SDNodeOrder); - DAG.AssignOrdering(t11.getNode(), SDNodeOrder); - DAG.AssignOrdering(t12.getNode(), SDNodeOrder); - DAG.AssignOrdering(t13.getNode(), SDNodeOrder); - DAG.AssignOrdering(t14.getNode(), SDNodeOrder); - DAG.AssignOrdering(TwoToFracPartOfX.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } } else { // No special expansion. result = DAG.getNode(ISD::FEXP, dl, getValue(I.getOperand(1)).getValueType(), getValue(I.getOperand(1))); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } setValue(&I, result); @@ -3317,15 +3088,11 @@ SelectionDAGBuilder::visitLog(CallInst &I) { SDValue Op = getValue(I.getOperand(1)); SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op); - DAG.AssignOrdering(Op1.getNode(), SDNodeOrder); - // Scale the exponent by log(2) [0.69314718f]. SDValue Exp = GetExponent(DAG, Op1, TLI, dl, SDNodeOrder); SDValue LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp, getF32Constant(DAG, 0x3f317218)); - DAG.AssignOrdering(LogOfExponent.getNode(), SDNodeOrder); - // Get the significand and build it into a floating-point number with // exponent of 1. SDValue X = GetSignificand(DAG, Op1, dl, SDNodeOrder); @@ -3348,12 +3115,6 @@ SelectionDAGBuilder::visitLog(CallInst &I) { result = DAG.getNode(ISD::FADD, dl, MVT::f32, LogOfExponent, LogOfMantissa); - - DAG.AssignOrdering(t0.getNode(), SDNodeOrder); - DAG.AssignOrdering(t1.getNode(), SDNodeOrder); - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(LogOfMantissa.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) { // For floating-point precision of 12: // @@ -3380,16 +3141,6 @@ SelectionDAGBuilder::visitLog(CallInst &I) { result = DAG.getNode(ISD::FADD, dl, MVT::f32, LogOfExponent, LogOfMantissa); - - DAG.AssignOrdering(t0.getNode(), SDNodeOrder); - DAG.AssignOrdering(t1.getNode(), SDNodeOrder); - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(LogOfMantissa.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18 // For floating-point precision of 18: // @@ -3424,27 +3175,12 @@ SelectionDAGBuilder::visitLog(CallInst &I) { result = DAG.getNode(ISD::FADD, dl, MVT::f32, LogOfExponent, LogOfMantissa); - - DAG.AssignOrdering(t0.getNode(), SDNodeOrder); - DAG.AssignOrdering(t1.getNode(), SDNodeOrder); - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(t7.getNode(), SDNodeOrder); - DAG.AssignOrdering(t8.getNode(), SDNodeOrder); - DAG.AssignOrdering(t9.getNode(), SDNodeOrder); - DAG.AssignOrdering(t10.getNode(), SDNodeOrder); - DAG.AssignOrdering(LogOfMantissa.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } } else { // No special expansion. result = DAG.getNode(ISD::FLOG, dl, getValue(I.getOperand(1)).getValueType(), getValue(I.getOperand(1))); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } setValue(&I, result); @@ -3462,13 +3198,9 @@ SelectionDAGBuilder::visitLog2(CallInst &I) { SDValue Op = getValue(I.getOperand(1)); SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op); - DAG.AssignOrdering(Op1.getNode(), SDNodeOrder); - // Get the exponent. SDValue LogOfExponent = GetExponent(DAG, Op1, TLI, dl, SDNodeOrder); - DAG.AssignOrdering(LogOfExponent.getNode(), SDNodeOrder); - // Get the significand and build it into a floating-point number with // exponent of 1. SDValue X = GetSignificand(DAG, Op1, dl, SDNodeOrder); @@ -3491,12 +3223,6 @@ SelectionDAGBuilder::visitLog2(CallInst &I) { result = DAG.getNode(ISD::FADD, dl, MVT::f32, LogOfExponent, Log2ofMantissa); - - DAG.AssignOrdering(t0.getNode(), SDNodeOrder); - DAG.AssignOrdering(t1.getNode(), SDNodeOrder); - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(Log2ofMantissa.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) { // For floating-point precision of 12: // @@ -3523,16 +3249,6 @@ SelectionDAGBuilder::visitLog2(CallInst &I) { result = DAG.getNode(ISD::FADD, dl, MVT::f32, LogOfExponent, Log2ofMantissa); - - DAG.AssignOrdering(t0.getNode(), SDNodeOrder); - DAG.AssignOrdering(t1.getNode(), SDNodeOrder); - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(Log2ofMantissa.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18 // For floating-point precision of 18: // @@ -3568,27 +3284,12 @@ SelectionDAGBuilder::visitLog2(CallInst &I) { result = DAG.getNode(ISD::FADD, dl, MVT::f32, LogOfExponent, Log2ofMantissa); - - DAG.AssignOrdering(t0.getNode(), SDNodeOrder); - DAG.AssignOrdering(t1.getNode(), SDNodeOrder); - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(t7.getNode(), SDNodeOrder); - DAG.AssignOrdering(t8.getNode(), SDNodeOrder); - DAG.AssignOrdering(t9.getNode(), SDNodeOrder); - DAG.AssignOrdering(t10.getNode(), SDNodeOrder); - DAG.AssignOrdering(Log2ofMantissa.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } } else { // No special expansion. result = DAG.getNode(ISD::FLOG2, dl, getValue(I.getOperand(1)).getValueType(), getValue(I.getOperand(1))); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } setValue(&I, result); @@ -3606,15 +3307,11 @@ SelectionDAGBuilder::visitLog10(CallInst &I) { SDValue Op = getValue(I.getOperand(1)); SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op); - DAG.AssignOrdering(Op1.getNode(), SDNodeOrder); - // Scale the exponent by log10(2) [0.30102999f]. SDValue Exp = GetExponent(DAG, Op1, TLI, dl, SDNodeOrder); SDValue LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp, getF32Constant(DAG, 0x3e9a209a)); - DAG.AssignOrdering(LogOfExponent.getNode(), SDNodeOrder); - // Get the significand and build it into a floating-point number with // exponent of 1. SDValue X = GetSignificand(DAG, Op1, dl, SDNodeOrder); @@ -3637,12 +3334,6 @@ SelectionDAGBuilder::visitLog10(CallInst &I) { result = DAG.getNode(ISD::FADD, dl, MVT::f32, LogOfExponent, Log10ofMantissa); - - DAG.AssignOrdering(t0.getNode(), SDNodeOrder); - DAG.AssignOrdering(t1.getNode(), SDNodeOrder); - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(Log10ofMantissa.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) { // For floating-point precision of 12: // @@ -3665,14 +3356,6 @@ SelectionDAGBuilder::visitLog10(CallInst &I) { result = DAG.getNode(ISD::FADD, dl, MVT::f32, LogOfExponent, Log10ofMantissa); - - DAG.AssignOrdering(t0.getNode(), SDNodeOrder); - DAG.AssignOrdering(t1.getNode(), SDNodeOrder); - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(Log10ofMantissa.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18 // For floating-point precision of 18: // @@ -3703,25 +3386,12 @@ SelectionDAGBuilder::visitLog10(CallInst &I) { result = DAG.getNode(ISD::FADD, dl, MVT::f32, LogOfExponent, Log10ofMantissa); - - DAG.AssignOrdering(t0.getNode(), SDNodeOrder); - DAG.AssignOrdering(t1.getNode(), SDNodeOrder); - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(t7.getNode(), SDNodeOrder); - DAG.AssignOrdering(t8.getNode(), SDNodeOrder); - DAG.AssignOrdering(Log10ofMantissa.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } } else { // No special expansion. result = DAG.getNode(ISD::FLOG10, dl, getValue(I.getOperand(1)).getValueType(), getValue(I.getOperand(1))); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } setValue(&I, result); @@ -3740,8 +3410,6 @@ SelectionDAGBuilder::visitExp2(CallInst &I) { SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Op); - DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder); - // FractionalPartOfX = x - (float)IntegerPartOfX; SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX); SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, Op, t1); @@ -3750,10 +3418,6 @@ SelectionDAGBuilder::visitExp2(CallInst &I) { IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX, DAG.getConstant(23, TLI.getPointerTy())); - DAG.AssignOrdering(t1.getNode(), SDNodeOrder); - DAG.AssignOrdering(X.getNode(), SDNodeOrder); - DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder); - if (LimitFloatPrecision <= 6) { // For floating-point precision of 6: // @@ -3775,14 +3439,6 @@ SelectionDAGBuilder::visitExp2(CallInst &I) { result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, TwoToFractionalPartOfX); - - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) { // For floating-point precision of 12: // @@ -3808,16 +3464,6 @@ SelectionDAGBuilder::visitExp2(CallInst &I) { result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, TwoToFractionalPartOfX); - - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(t7.getNode(), SDNodeOrder); - DAG.AssignOrdering(t8.getNode(), SDNodeOrder); - DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18 // For floating-point precision of 18: // @@ -3854,29 +3500,12 @@ SelectionDAGBuilder::visitExp2(CallInst &I) { result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, TwoToFractionalPartOfX); - - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(t7.getNode(), SDNodeOrder); - DAG.AssignOrdering(t8.getNode(), SDNodeOrder); - DAG.AssignOrdering(t9.getNode(), SDNodeOrder); - DAG.AssignOrdering(t10.getNode(), SDNodeOrder); - DAG.AssignOrdering(t11.getNode(), SDNodeOrder); - DAG.AssignOrdering(t12.getNode(), SDNodeOrder); - DAG.AssignOrdering(t13.getNode(), SDNodeOrder); - DAG.AssignOrdering(t14.getNode(), SDNodeOrder); - DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } } else { // No special expansion. result = DAG.getNode(ISD::FEXP2, dl, getValue(I.getOperand(1)).getValueType(), getValue(I.getOperand(1))); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } setValue(&I, result); @@ -3918,17 +3547,10 @@ SelectionDAGBuilder::visitPow(CallInst &I) { SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX); SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0, t1); - DAG.AssignOrdering(t0.getNode(), SDNodeOrder); - DAG.AssignOrdering(t1.getNode(), SDNodeOrder); - DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder); - DAG.AssignOrdering(X.getNode(), SDNodeOrder); - // IntegerPartOfX <<= 23; IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX, DAG.getConstant(23, TLI.getPointerTy())); - DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder); - if (LimitFloatPrecision <= 6) { // For floating-point precision of 6: // @@ -3950,14 +3572,6 @@ SelectionDAGBuilder::visitPow(CallInst &I) { result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, TwoToFractionalPartOfX); - - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) { // For floating-point precision of 12: // @@ -3983,16 +3597,6 @@ SelectionDAGBuilder::visitPow(CallInst &I) { result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, TwoToFractionalPartOfX); - - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(t7.getNode(), SDNodeOrder); - DAG.AssignOrdering(t8.getNode(), SDNodeOrder); - DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18 // For floating-point precision of 18: // @@ -4029,22 +3633,6 @@ SelectionDAGBuilder::visitPow(CallInst &I) { result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, TwoToFractionalPartOfX); - - DAG.AssignOrdering(t2.getNode(), SDNodeOrder); - DAG.AssignOrdering(t3.getNode(), SDNodeOrder); - DAG.AssignOrdering(t4.getNode(), SDNodeOrder); - DAG.AssignOrdering(t5.getNode(), SDNodeOrder); - DAG.AssignOrdering(t6.getNode(), SDNodeOrder); - DAG.AssignOrdering(t7.getNode(), SDNodeOrder); - DAG.AssignOrdering(t8.getNode(), SDNodeOrder); - DAG.AssignOrdering(t9.getNode(), SDNodeOrder); - DAG.AssignOrdering(t10.getNode(), SDNodeOrder); - DAG.AssignOrdering(t11.getNode(), SDNodeOrder); - DAG.AssignOrdering(t12.getNode(), SDNodeOrder); - DAG.AssignOrdering(t13.getNode(), SDNodeOrder); - DAG.AssignOrdering(t14.getNode(), SDNodeOrder); - DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } } else { // No special expansion. @@ -4052,7 +3640,6 @@ SelectionDAGBuilder::visitPow(CallInst &I) { getValue(I.getOperand(1)).getValueType(), getValue(I.getOperand(1)), getValue(I.getOperand(2))); - DAG.AssignOrdering(result.getNode(), SDNodeOrder); } setValue(&I, result); @@ -4129,16 +3716,12 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { case Intrinsic::vaend: visitVAEnd(I); return 0; case Intrinsic::vacopy: visitVACopy(I); return 0; case Intrinsic::returnaddress: - Res = DAG.getNode(ISD::RETURNADDR, dl, TLI.getPointerTy(), - getValue(I.getOperand(1))); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::RETURNADDR, dl, TLI.getPointerTy(), + getValue(I.getOperand(1)))); return 0; case Intrinsic::frameaddress: - Res = DAG.getNode(ISD::FRAMEADDR, dl, TLI.getPointerTy(), - getValue(I.getOperand(1))); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::FRAMEADDR, dl, TLI.getPointerTy(), + getValue(I.getOperand(1)))); return 0; case Intrinsic::setjmp: return "_setjmp"+!TLI.usesUnderscoreSetJmp(); @@ -4149,10 +3732,8 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { SDValue Op2 = getValue(I.getOperand(2)); SDValue Op3 = getValue(I.getOperand(3)); unsigned Align = cast<ConstantInt>(I.getOperand(4))->getZExtValue(); - Res = DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false, - I.getOperand(1), 0, I.getOperand(2), 0); - DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + DAG.setRoot(DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false, + I.getOperand(1), 0, I.getOperand(2), 0)); return 0; } case Intrinsic::memset: { @@ -4160,10 +3741,8 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { SDValue Op2 = getValue(I.getOperand(2)); SDValue Op3 = getValue(I.getOperand(3)); unsigned Align = cast<ConstantInt>(I.getOperand(4))->getZExtValue(); - Res = DAG.getMemset(getRoot(), dl, Op1, Op2, Op3, Align, - I.getOperand(1), 0); - DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + DAG.setRoot(DAG.getMemset(getRoot(), dl, Op1, Op2, Op3, Align, + I.getOperand(1), 0)); return 0; } case Intrinsic::memmove: { @@ -4179,20 +3758,18 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { Size = C->getZExtValue(); if (AA->alias(I.getOperand(1), Size, I.getOperand(2), Size) == AliasAnalysis::NoAlias) { - Res = DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false, - I.getOperand(1), 0, I.getOperand(2), 0); - DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + DAG.setRoot(DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false, + I.getOperand(1), 0, I.getOperand(2), 0)); return 0; } - Res = DAG.getMemmove(getRoot(), dl, Op1, Op2, Op3, Align, - I.getOperand(1), 0, I.getOperand(2), 0); - DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + DAG.setRoot(DAG.getMemmove(getRoot(), dl, Op1, Op2, Op3, Align, + I.getOperand(1), 0, I.getOperand(2), 0)); return 0; } case Intrinsic::dbg_declare: { + // FIXME: currently, we get here only if OptLevel != CodeGenOpt::None. + // The real handling of this intrinsic is in FastISel. if (OptLevel != CodeGenOpt::None) // FIXME: Variable debug info is not supported here. return 0; @@ -4205,6 +3782,8 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { MDNode *Variable = DI.getVariable(); Value *Address = DI.getAddress(); + if (!Address) + return 0; if (BitCastInst *BCI = dyn_cast<BitCastInst>(Address)) Address = BCI->getOperand(0); AllocaInst *AI = dyn_cast<AllocaInst>(Address); @@ -4222,6 +3801,39 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { MMI->setVariableDbgInfo(Variable, FI, Dbg); return 0; } + case Intrinsic::dbg_value: { + // FIXME: currently, we get here only if OptLevel != CodeGenOpt::None. + // The real handling of this intrinsic is in FastISel. + if (OptLevel != CodeGenOpt::None) + // FIXME: Variable debug info is not supported here. + return 0; + DwarfWriter *DW = DAG.getDwarfWriter(); + if (!DW) + return 0; + DbgValueInst &DI = cast<DbgValueInst>(I); + if (!DIDescriptor::ValidDebugInfo(DI.getVariable(), CodeGenOpt::None)) + return 0; + + MDNode *Variable = DI.getVariable(); + Value *V = DI.getValue(); + if (!V) + return 0; + if (BitCastInst *BCI = dyn_cast<BitCastInst>(V)) + V = BCI->getOperand(0); + AllocaInst *AI = dyn_cast<AllocaInst>(V); + // Don't handle byval struct arguments or VLAs, for example. + if (!AI) + return 0; + DenseMap<const AllocaInst*, int>::iterator SI = + FuncInfo.StaticAllocaMap.find(AI); + if (SI == FuncInfo.StaticAllocaMap.end()) + return 0; // VLAs. + int FI = SI->second; + if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo()) + if (MDNode *Dbg = DI.getMetadata("dbg")) + MMI->setVariableDbgInfo(Variable, FI, Dbg); + return 0; + } case Intrinsic::eh_exception: { // Insert the EXCEPTIONADDR instruction. assert(CurMBB->isLandingPad() &&"Call to eh.exception not in landing pad!"); @@ -4231,7 +3843,6 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { SDValue Op = DAG.getNode(ISD::EXCEPTIONADDR, dl, VTs, Ops, 1); setValue(&I, Op); DAG.setRoot(Op.getValue(1)); - DAG.AssignOrdering(Op.getNode(), SDNodeOrder); return 0; } @@ -4255,13 +3866,8 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { Ops[0] = getValue(I.getOperand(1)); Ops[1] = getRoot(); SDValue Op = DAG.getNode(ISD::EHSELECTION, dl, VTs, Ops, 2); - DAG.setRoot(Op.getValue(1)); - - Res = DAG.getSExtOrTrunc(Op, dl, MVT::i32); - setValue(&I, Res); - DAG.AssignOrdering(Op.getNode(), SDNodeOrder); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getSExtOrTrunc(Op, dl, MVT::i32)); return 0; } @@ -4279,7 +3885,6 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { } setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); return 0; } @@ -4287,13 +3892,11 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { case Intrinsic::eh_return_i64: if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo()) { MMI->setCallsEHReturn(true); - Res = DAG.getNode(ISD::EH_RETURN, dl, - MVT::Other, - getControlRoot(), - getValue(I.getOperand(1)), - getValue(I.getOperand(2))); - DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + DAG.setRoot(DAG.getNode(ISD::EH_RETURN, dl, + MVT::Other, + getControlRoot(), + getValue(I.getOperand(1)), + getValue(I.getOperand(2)))); } else { setValue(&I, DAG.getConstant(0, TLI.getPointerTy())); } @@ -4316,15 +3919,20 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { SDValue FA = DAG.getNode(ISD::FRAMEADDR, dl, TLI.getPointerTy(), DAG.getConstant(0, TLI.getPointerTy())); - Res = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), - FA, Offset); - setValue(&I, Res); - DAG.AssignOrdering(CfaArg.getNode(), SDNodeOrder); - DAG.AssignOrdering(Offset.getNode(), SDNodeOrder); - DAG.AssignOrdering(FA.getNode(), SDNodeOrder); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), + FA, Offset)); + return 0; + } + case Intrinsic::eh_sjlj_callsite: { + MachineModuleInfo *MMI = DAG.getMachineModuleInfo(); + ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1)); + assert(CI && "Non-constant call site value in eh.sjlj.callsite!"); + assert(MMI->getCurrentCallSite() == 0 && "Overlapping call sites!"); + + MMI->setCurrentCallSite(CI->getZExtValue()); return 0; } + case Intrinsic::convertff: case Intrinsic::convertfsi: case Intrinsic::convertfui: @@ -4355,35 +3963,26 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { getValue(I.getOperand(3)), Code); setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); return 0; } case Intrinsic::sqrt: - Res = DAG.getNode(ISD::FSQRT, dl, - getValue(I.getOperand(1)).getValueType(), - getValue(I.getOperand(1))); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::FSQRT, dl, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)))); return 0; case Intrinsic::powi: - Res = ExpandPowI(dl, getValue(I.getOperand(1)), getValue(I.getOperand(2)), - DAG); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, ExpandPowI(dl, getValue(I.getOperand(1)), + getValue(I.getOperand(2)), DAG)); return 0; case Intrinsic::sin: - Res = DAG.getNode(ISD::FSIN, dl, - getValue(I.getOperand(1)).getValueType(), - getValue(I.getOperand(1))); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::FSIN, dl, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)))); return 0; case Intrinsic::cos: - Res = DAG.getNode(ISD::FCOS, dl, - getValue(I.getOperand(1)).getValueType(), - getValue(I.getOperand(1))); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::FCOS, dl, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)))); return 0; case Intrinsic::log: visitLog(I); @@ -4405,9 +4004,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { return 0; case Intrinsic::pcmarker: { SDValue Tmp = getValue(I.getOperand(1)); - Res = DAG.getNode(ISD::PCMARKER, dl, MVT::Other, getRoot(), Tmp); - DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + DAG.setRoot(DAG.getNode(ISD::PCMARKER, dl, MVT::Other, getRoot(), Tmp)); return 0; } case Intrinsic::readcyclecounter: { @@ -4417,38 +4014,29 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { &Op, 1); setValue(&I, Res); DAG.setRoot(Res.getValue(1)); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); return 0; } case Intrinsic::bswap: - Res = DAG.getNode(ISD::BSWAP, dl, - getValue(I.getOperand(1)).getValueType(), - getValue(I.getOperand(1))); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::BSWAP, dl, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)))); return 0; case Intrinsic::cttz: { SDValue Arg = getValue(I.getOperand(1)); EVT Ty = Arg.getValueType(); - Res = DAG.getNode(ISD::CTTZ, dl, Ty, Arg); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::CTTZ, dl, Ty, Arg)); return 0; } case Intrinsic::ctlz: { SDValue Arg = getValue(I.getOperand(1)); EVT Ty = Arg.getValueType(); - Res = DAG.getNode(ISD::CTLZ, dl, Ty, Arg); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::CTLZ, dl, Ty, Arg)); return 0; } case Intrinsic::ctpop: { SDValue Arg = getValue(I.getOperand(1)); EVT Ty = Arg.getValueType(); - Res = DAG.getNode(ISD::CTPOP, dl, Ty, Arg); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::CTPOP, dl, Ty, Arg)); return 0; } case Intrinsic::stacksave: { @@ -4457,14 +4045,11 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { DAG.getVTList(TLI.getPointerTy(), MVT::Other), &Op, 1); setValue(&I, Res); DAG.setRoot(Res.getValue(1)); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); return 0; } case Intrinsic::stackrestore: { Res = getValue(I.getOperand(1)); - Res = DAG.getNode(ISD::STACKRESTORE, dl, MVT::Other, getRoot(), Res); - DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + DAG.setRoot(DAG.getNode(ISD::STACKRESTORE, dl, MVT::Other, getRoot(), Res)); return 0; } case Intrinsic::stackprotector: { @@ -4484,10 +4069,9 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { // Store the stack protector onto the stack. Res = DAG.getStore(getRoot(), getCurDebugLoc(), Src, FIN, PseudoSourceValue::getFixedStack(FI), - 0, true); + 0, true, false, 0); setValue(&I, Res); DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); return 0; } case Intrinsic::objectsize: { @@ -4505,7 +4089,6 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { Res = DAG.getConstant(0, Ty); setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); return 0; } case Intrinsic::var_annotation: @@ -4529,7 +4112,6 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { setValue(&I, Res); DAG.setRoot(Res.getValue(1)); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); return 0; } case Intrinsic::gcroot: @@ -4546,14 +4128,10 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { llvm_unreachable("GC failed to lower gcread/gcwrite intrinsics!"); return 0; case Intrinsic::flt_rounds: - Res = DAG.getNode(ISD::FLT_ROUNDS_, dl, MVT::i32); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getNode(ISD::FLT_ROUNDS_, dl, MVT::i32)); return 0; case Intrinsic::trap: - Res = DAG.getNode(ISD::TRAP, dl,MVT::Other, getRoot()); - DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + DAG.setRoot(DAG.getNode(ISD::TRAP, dl,MVT::Other, getRoot())); return 0; case Intrinsic::uadd_with_overflow: return implVisitAluOverflow(I, ISD::UADDO); @@ -4574,9 +4152,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { Ops[1] = getValue(I.getOperand(1)); Ops[2] = getValue(I.getOperand(2)); Ops[3] = getValue(I.getOperand(3)); - Res = DAG.getNode(ISD::PREFETCH, dl, MVT::Other, &Ops[0], 4); - DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + DAG.setRoot(DAG.getNode(ISD::PREFETCH, dl, MVT::Other, &Ops[0], 4)); return 0; } @@ -4586,9 +4162,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { for (int x = 1; x < 6; ++x) Ops[x] = getValue(I.getOperand(x)); - Res = DAG.getNode(ISD::MEMBARRIER, dl, MVT::Other, &Ops[0], 6); - DAG.setRoot(Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + DAG.setRoot(DAG.getNode(ISD::MEMBARRIER, dl, MVT::Other, &Ops[0], 6)); return 0; } case Intrinsic::atomic_cmp_swap: { @@ -4603,7 +4177,6 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { I.getOperand(1)); setValue(&I, L); DAG.setRoot(L.getValue(1)); - DAG.AssignOrdering(L.getNode(), SDNodeOrder); return 0; } case Intrinsic::atomic_load_add: @@ -4632,9 +4205,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { case Intrinsic::invariant_start: case Intrinsic::lifetime_start: // Discard region information. - Res = DAG.getUNDEF(TLI.getPointerTy()); - setValue(&I, Res); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); + setValue(&I, DAG.getUNDEF(TLI.getPointerTy())); return 0; case Intrinsic::invariant_end: case Intrinsic::lifetime_end: @@ -4649,19 +4220,25 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { /// between it and the return. /// /// This function only tests target-independent requirements. -/// For target-dependent requirements, a target should override -/// TargetLowering::IsEligibleForTailCallOptimization. -/// static bool -isInTailCallPosition(const Instruction *I, Attributes CalleeRetAttr, +isInTailCallPosition(CallSite CS, Attributes CalleeRetAttr, const TargetLowering &TLI) { + const Instruction *I = CS.getInstruction(); const BasicBlock *ExitBB = I->getParent(); const TerminatorInst *Term = ExitBB->getTerminator(); const ReturnInst *Ret = dyn_cast<ReturnInst>(Term); const Function *F = ExitBB->getParent(); - // The block must end in a return statement or an unreachable. - if (!Ret && !isa<UnreachableInst>(Term)) return false; + // The block must end in a return statement or unreachable. + // + // FIXME: Decline tailcall if it's not guaranteed and if the block ends in + // an unreachable, for now. The way tailcall optimization is currently + // implemented means it will add an epilogue followed by a jump. That is + // not profitable. Also, if the callee is a special function (e.g. + // longjmp on x86), it can end up causing miscompilation that has not + // been fully understood. + if (!Ret && + (!GuaranteedTailCallOpt || !isa<UnreachableInst>(Term))) return false; // If I will have a chain, make sure no other instruction that will have a // chain interposes between I and the return. @@ -4690,6 +4267,10 @@ isInTailCallPosition(const Instruction *I, Attributes CalleeRetAttr, if ((CalleeRetAttr ^ CallerRetAttr) & ~Attribute::NoAlias) return false; + // It's not safe to eliminate the sign / zero extension of the return value. + if ((CallerRetAttr & Attribute::ZExt) || (CallerRetAttr & Attribute::SExt)) + return false; + // Otherwise, make sure the unmodified return value of I is the return value. for (const Instruction *U = dyn_cast<Instruction>(Ret->getOperand(0)); ; U = dyn_cast<Instruction>(U->getOperand(0))) { @@ -4785,6 +4366,15 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee, // used to detect deletion of the invoke via the MachineModuleInfo. BeginLabel = MMI->NextLabelID(); + // For SjLj, keep track of which landing pads go with which invokes + // so as to maintain the ordering of pads in the LSDA. + unsigned CallSiteIndex = MMI->getCurrentCallSite(); + if (CallSiteIndex) { + MMI->setCallSiteBeginLabel(BeginLabel, CallSiteIndex); + // Now that the call site is handled, stop tracking it. + MMI->setCurrentCallSite(0); + } + // Both PendingLoads and PendingExports must be flushed here; // this call might not return. (void)getRoot(); @@ -4795,9 +4385,7 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee, // Check if target-independent constraints permit a tail call here. // Target-dependent constraints are checked within TLI.LowerCallTo. if (isTailCall && - !isInTailCallPosition(CS.getInstruction(), - CS.getAttributes().getRetAttributes(), - TLI)) + !isInTailCallPosition(CS, CS.getAttributes().getRetAttributes(), TLI)) isTailCall = false; std::pair<SDValue,SDValue> Result = @@ -4815,7 +4403,6 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee, "Null value expected with tail call!"); if (Result.first.getNode()) { setValue(CS.getInstruction(), Result.first); - DAG.AssignOrdering(Result.first.getNode(), SDNodeOrder); } else if (!CanLowerReturn && Result.second.getNode()) { // The instruction result is the result of loading from the // hidden sret parameter. @@ -4834,7 +4421,7 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee, DemoteStackSlot, DAG.getConstant(Offsets[i], PtrVT)); SDValue L = DAG.getLoad(OutVTs[i], getCurDebugLoc(), Result.second, - Add, NULL, Offsets[i], false, 1); + Add, NULL, Offsets[i], false, false, 1); Values[i] = L; Chains[i] = L.getValue(1); } @@ -4860,27 +4447,22 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee, getCopyFromParts(DAG, getCurDebugLoc(), SDNodeOrder, &Values[CurReg], NumRegs, RegisterVT, VT, AssertOp); ReturnValues.push_back(ReturnValue); - DAG.AssignOrdering(ReturnValue.getNode(), SDNodeOrder); CurReg += NumRegs; } - SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), - DAG.getVTList(&RetTys[0], RetTys.size()), - &ReturnValues[0], ReturnValues.size()); - setValue(CS.getInstruction(), Res); + setValue(CS.getInstruction(), + DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), + DAG.getVTList(&RetTys[0], RetTys.size()), + &ReturnValues[0], ReturnValues.size())); - DAG.AssignOrdering(Chain.getNode(), SDNodeOrder); - DAG.AssignOrdering(Res.getNode(), SDNodeOrder); } // As a special case, a null chain means that a tail call has been emitted and // the DAG root is already updated. - if (Result.second.getNode()) { + if (Result.second.getNode()) DAG.setRoot(Result.second); - DAG.AssignOrdering(Result.second.getNode(), SDNodeOrder); - } else { + else HasTailCall = true; - } if (LandingPad && MMI) { // Insert a label at the end of the invoke call to mark the try range. This @@ -4941,7 +4523,8 @@ static SDValue getMemCmpLoad(Value *PtrVal, MVT LoadVT, const Type *LoadTy, SDValue Ptr = Builder.getValue(PtrVal); SDValue LoadVal = Builder.DAG.getLoad(LoadVT, Builder.getCurDebugLoc(), Root, Ptr, PtrVal /*SrcValue*/, 0/*SVOffset*/, - false /*volatile*/, 1 /* align=1 */); + false /*volatile*/, + false /*nontemporal*/, 1 /* align=1 */); if (!ConstantMemory) Builder.PendingLoads.push_back(LoadVal.getValue(1)); @@ -5054,7 +4637,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) { StringRef Name = F->getName(); if (Name == "copysign" || Name == "copysignf") { if (I.getNumOperands() == 3 && // Basic sanity checks. - I.getOperand(1)->getType()->isFloatingPoint() && + I.getOperand(1)->getType()->isFloatingPointTy() && I.getType() == I.getOperand(1)->getType() && I.getType() == I.getOperand(2)->getType()) { SDValue LHS = getValue(I.getOperand(1)); @@ -5065,7 +4648,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) { } } else if (Name == "fabs" || Name == "fabsf" || Name == "fabsl") { if (I.getNumOperands() == 2 && // Basic sanity checks. - I.getOperand(1)->getType()->isFloatingPoint() && + I.getOperand(1)->getType()->isFloatingPointTy() && I.getType() == I.getOperand(1)->getType()) { SDValue Tmp = getValue(I.getOperand(1)); setValue(&I, DAG.getNode(ISD::FABS, getCurDebugLoc(), @@ -5074,7 +4657,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) { } } else if (Name == "sin" || Name == "sinf" || Name == "sinl") { if (I.getNumOperands() == 2 && // Basic sanity checks. - I.getOperand(1)->getType()->isFloatingPoint() && + I.getOperand(1)->getType()->isFloatingPointTy() && I.getType() == I.getOperand(1)->getType() && I.onlyReadsMemory()) { SDValue Tmp = getValue(I.getOperand(1)); @@ -5084,7 +4667,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) { } } else if (Name == "cos" || Name == "cosf" || Name == "cosl") { if (I.getNumOperands() == 2 && // Basic sanity checks. - I.getOperand(1)->getType()->isFloatingPoint() && + I.getOperand(1)->getType()->isFloatingPointTy() && I.getType() == I.getOperand(1)->getType() && I.onlyReadsMemory()) { SDValue Tmp = getValue(I.getOperand(1)); @@ -5094,7 +4677,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) { } } else if (Name == "sqrt" || Name == "sqrtf" || Name == "sqrtl") { if (I.getNumOperands() == 2 && // Basic sanity checks. - I.getOperand(1)->getType()->isFloatingPoint() && + I.getOperand(1)->getType()->isFloatingPointTy() && I.getType() == I.getOperand(1)->getType() && I.onlyReadsMemory()) { SDValue Tmp = getValue(I.getOperand(1)); @@ -5120,9 +4703,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) { // Check if we can potentially perform a tail call. More detailed checking is // be done within LowerCallTo, after more information about the call is known. - bool isTailCall = PerformTailCallOpt && I.isTailCall(); - - LowerCallTo(&I, Callee, isTailCall); + LowerCallTo(&I, Callee, I.isTailCall()); } /// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from @@ -5152,7 +4733,6 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl, } Chain = P.getValue(1); - DAG.AssignOrdering(P.getNode(), Order); // If the source register was virtual and if we know something about it, // add an assert node. @@ -5188,11 +4768,9 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl, else if (NumZeroBits >= RegSize-32) isSExt = false, FromVT = MVT::i32; // ASSERT ZEXT 32 - if (FromVT != MVT::Other) { + if (FromVT != MVT::Other) P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext, dl, RegisterVT, P, DAG.getValueType(FromVT)); - DAG.AssignOrdering(P.getNode(), Order); - } } } @@ -5201,16 +4779,13 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl, Values[Value] = getCopyFromParts(DAG, dl, Order, Parts.begin(), NumRegs, RegisterVT, ValueVT); - DAG.AssignOrdering(Values[Value].getNode(), Order); Part += NumRegs; Parts.clear(); } - SDValue Res = DAG.getNode(ISD::MERGE_VALUES, dl, - DAG.getVTList(&ValueVTs[0], ValueVTs.size()), - &Values[0], ValueVTs.size()); - DAG.AssignOrdering(Res.getNode(), Order); - return Res; + return DAG.getNode(ISD::MERGE_VALUES, dl, + DAG.getVTList(&ValueVTs[0], ValueVTs.size()), + &Values[0], ValueVTs.size()); } /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the @@ -5246,7 +4821,6 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl, } Chains[i] = Part.getValue(0); - DAG.AssignOrdering(Part.getNode(), Order); } if (NumRegs == 1 || Flag) @@ -5263,8 +4837,6 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl, Chain = Chains[NumRegs-1]; else Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Chains[0], NumRegs); - - DAG.AssignOrdering(Chain.getNode(), Order); } /// AddInlineAsmOperands - Add this value to the specified inlineasm node @@ -5281,16 +4853,12 @@ void RegsForValue::AddInlineAsmOperands(unsigned Code, SDValue Res = DAG.getTargetConstant(Flag, MVT::i32); Ops.push_back(Res); - DAG.AssignOrdering(Res.getNode(), Order); - for (unsigned Value = 0, Reg = 0, e = ValueVTs.size(); Value != e; ++Value) { unsigned NumRegs = TLI->getNumRegisters(*DAG.getContext(), ValueVTs[Value]); EVT RegisterVT = RegVTs[Value]; for (unsigned i = 0; i != NumRegs; ++i) { assert(Reg < Regs.size() && "Mismatch in # registers expected"); - SDValue Res = DAG.getRegister(Regs[Reg++], RegisterVT); - Ops.push_back(Res); - DAG.AssignOrdering(Res.getNode(), Order); + Ops.push_back(DAG.getRegister(Regs[Reg++], RegisterVT)); } } } @@ -5309,7 +4877,7 @@ isAllocatableRegister(unsigned Reg, MachineFunction &MF, EVT ThisVT = MVT::Other; const TargetRegisterClass *RC = *RCI; - // If none of the the value types for this register class are valid, we + // If none of the value types for this register class are valid, we // can't use it. For example, 64-bit reg classes on 32-bit targets. for (TargetRegisterClass::vt_iterator I = RC->vt_begin(), E = RC->vt_end(); I != E; ++I) { @@ -5509,8 +5077,6 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo, RegVT, OpInfo.CallOperand); OpInfo.ConstraintVT = RegVT; } - - DAG.AssignOrdering(OpInfo.CallOperand.getNode(), SDNodeOrder); } NumRegs = TLI.getNumRegisters(Context, OpInfo.ConstraintVT); @@ -5776,7 +5342,8 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) { int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align, false); SDValue StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy()); Chain = DAG.getStore(Chain, getCurDebugLoc(), - OpInfo.CallOperand, StackSlot, NULL, 0); + OpInfo.CallOperand, StackSlot, NULL, 0, + false, false, 0); OpInfo.CallOperand = StackSlot; } @@ -5972,7 +5539,8 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) { "Don't know how to handle indirect register inputs yet!"); // Copy the input into the appropriate registers. - if (OpInfo.AssignedRegs.Regs.empty()) { + if (OpInfo.AssignedRegs.Regs.empty() || + !OpInfo.AssignedRegs.areValueTypesLegal()) { llvm_report_error("Couldn't allocate input reg for" " constraint '"+ OpInfo.ConstraintCode +"'!"); } @@ -6061,7 +5629,8 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) { SDValue Val = DAG.getStore(Chain, getCurDebugLoc(), StoresToEmit[i].first, getValue(StoresToEmit[i].second), - StoresToEmit[i].second, 0); + StoresToEmit[i].second, 0, + false, false, 0); OutChains.push_back(Val); } @@ -6116,9 +5685,6 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, SDValue Callee, ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl, unsigned Order) { - assert((!isTailCall || PerformTailCallOpt) && - "isTailCall set when tail-call optimizations are disabled!"); - // Handle all of the outgoing arguments. SmallVector<ISD::OutputArg, 32> Outs; for (unsigned i = 0, e = Args.size(); i != e; ++i) { @@ -6207,12 +5773,6 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, } } - // Check if target-dependent constraints permit a tail call here. - // Target-independent constraints should be checked by the caller. - if (isTailCall && - !IsEligibleForTailCallOptimization(Callee, CallConv, isVarArg, Ins, DAG)) - isTailCall = false; - SmallVector<SDValue, 4> InVals; Chain = LowerCall(Chain, Callee, CallConv, isVarArg, isTailCall, Outs, Ins, dl, DAG, InVals); @@ -6231,8 +5791,6 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, "LowerCall emitted a value with the wrong type!"); }); - DAG.AssignOrdering(Chain.getNode(), Order); - // For a tail call, the return value is merely live-out and there aren't // any nodes in the DAG representing it. Return a special value to // indicate that a tail call has been emitted and no more Instructions @@ -6256,11 +5814,9 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, EVT RegisterVT = getRegisterType(RetTy->getContext(), VT); unsigned NumRegs = getNumRegisters(RetTy->getContext(), VT); - SDValue ReturnValue = - getCopyFromParts(DAG, dl, Order, &InVals[CurReg], NumRegs, - RegisterVT, VT, AssertOp); - ReturnValues.push_back(ReturnValue); - DAG.AssignOrdering(ReturnValue.getNode(), Order); + ReturnValues.push_back(getCopyFromParts(DAG, dl, Order, &InVals[CurReg], + NumRegs, RegisterVT, VT, + AssertOp)); CurReg += NumRegs; } @@ -6273,7 +5829,6 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, SDValue Res = DAG.getNode(ISD::MERGE_VALUES, dl, DAG.getVTList(&RetTys[0], RetTys.size()), &ReturnValues[0], ReturnValues.size()); - DAG.AssignOrdering(Res.getNode(), Order); return std::make_pair(Res, Chain); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index db656e35a4a86..bc4b33dff12f8 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -342,6 +342,11 @@ public: void CopyValueToVirtualRegister(Value *V, unsigned Reg); + /// AssignOrderingToNode - Assign an ordering to the node. The order is gotten + /// from how the code appeared in the source. The ordering is used by the + /// scheduler to effectively turn off scheduling. + void AssignOrderingToNode(const SDNode *Node); + void visit(Instruction &I); void visit(unsigned Opcode, User &I); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 2bec964ace12e..eead526f099e1 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -457,6 +457,21 @@ public: }; } +/// TrivialTruncElim - Eliminate some trivial nops that can result from +/// ShrinkDemandedOps: (trunc (ext n)) -> n. +static bool TrivialTruncElim(SDValue Op, + TargetLowering::TargetLoweringOpt &TLO) { + SDValue N0 = Op.getOperand(0); + EVT VT = Op.getValueType(); + if ((N0.getOpcode() == ISD::ZERO_EXTEND || + N0.getOpcode() == ISD::SIGN_EXTEND || + N0.getOpcode() == ISD::ANY_EXTEND) && + N0.getOperand(0).getValueType() == VT) { + return TLO.CombineTo(Op, N0.getOperand(0)); + } + return false; +} + /// ShrinkDemandedOps - A late transformation pass that shrink expressions /// using TargetLowering::TargetLoweringOpt::ShrinkDemandedOp. It converts /// x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free. @@ -489,7 +504,9 @@ void SelectionDAGISel::ShrinkDemandedOps() { APInt Demanded = APInt::getAllOnesValue(BitWidth); APInt KnownZero, KnownOne; if (TLI.SimplifyDemandedBits(SDValue(N, 0), Demanded, - KnownZero, KnownOne, TLO)) { + KnownZero, KnownOne, TLO) || + (N->getOpcode() == ISD::TRUNCATE && + TrivialTruncElim(SDValue(N, 0), TLO))) { // Revisit the node. Worklist.erase(std::remove(Worklist.begin(), Worklist.end(), N), Worklist.end()); @@ -801,7 +818,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, // landing pad can thus be detected via the MachineModuleInfo. unsigned LabelID = MMI->addLandingPad(BB); - const TargetInstrDesc &II = TII.get(TargetInstrInfo::EH_LABEL); + const TargetInstrDesc &II = TII.get(TargetOpcode::EH_LABEL); BuildMI(BB, SDB->getCurDebugLoc(), II).addImm(LabelID); // Mark exception register as live in. @@ -953,7 +970,7 @@ SelectionDAGISel::FinishBasicBlock() { SDB->BitTestCases.empty()) { for (unsigned i = 0, e = SDB->PHINodesToUpdate.size(); i != e; ++i) { MachineInstr *PHI = SDB->PHINodesToUpdate[i].first; - assert(PHI->getOpcode() == TargetInstrInfo::PHI && + assert(PHI->isPHI() && "This is not a machine PHI node that we are updating!"); PHI->addOperand(MachineOperand::CreateReg(SDB->PHINodesToUpdate[i].second, false)); @@ -1000,7 +1017,7 @@ SelectionDAGISel::FinishBasicBlock() { for (unsigned pi = 0, pe = SDB->PHINodesToUpdate.size(); pi != pe; ++pi) { MachineInstr *PHI = SDB->PHINodesToUpdate[pi].first; MachineBasicBlock *PHIBB = PHI->getParent(); - assert(PHI->getOpcode() == TargetInstrInfo::PHI && + assert(PHI->isPHI() && "This is not a machine PHI node that we are updating!"); // This is "default" BB. We have two jumps to it. From "header" BB and // from last "case" BB. @@ -1056,7 +1073,7 @@ SelectionDAGISel::FinishBasicBlock() { for (unsigned pi = 0, pe = SDB->PHINodesToUpdate.size(); pi != pe; ++pi) { MachineInstr *PHI = SDB->PHINodesToUpdate[pi].first; MachineBasicBlock *PHIBB = PHI->getParent(); - assert(PHI->getOpcode() == TargetInstrInfo::PHI && + assert(PHI->isPHI() && "This is not a machine PHI node that we are updating!"); // "default" BB. We can go there only from header BB. if (PHIBB == SDB->JTCases[i].second.Default) { @@ -1079,7 +1096,7 @@ SelectionDAGISel::FinishBasicBlock() { // need to update PHI nodes in that block. for (unsigned i = 0, e = SDB->PHINodesToUpdate.size(); i != e; ++i) { MachineInstr *PHI = SDB->PHINodesToUpdate[i].first; - assert(PHI->getOpcode() == TargetInstrInfo::PHI && + assert(PHI->isPHI() && "This is not a machine PHI node that we are updating!"); if (BB->isSuccessor(PHI->getParent())) { PHI->addOperand(MachineOperand::CreateReg(SDB->PHINodesToUpdate[i].second, @@ -1116,7 +1133,7 @@ SelectionDAGISel::FinishBasicBlock() { // BB may have been removed from the CFG if a branch was constant folded. if (ThisBB->isSuccessor(BB)) { for (MachineBasicBlock::iterator Phi = BB->begin(); - Phi != BB->end() && Phi->getOpcode() == TargetInstrInfo::PHI; + Phi != BB->end() && Phi->isPHI(); ++Phi) { // This value for this PHI node is recorded in PHINodesToUpdate. for (unsigned pn = 0; ; ++pn) { @@ -1324,8 +1341,7 @@ static bool findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse, /// isNonImmUse - Start searching from Root up the DAG to check is Def can /// be reached. Return true if that's the case. However, ignore direct uses /// by ImmedUse (which would be U in the example illustrated in -/// IsLegalAndProfitableToFold) and by Root (which can happen in the store -/// case). +/// IsLegalToFold) and by Root (which can happen in the store case). /// FIXME: to be really generic, we should allow direct use by any node /// that is being folded. But realisticly since we only fold loads which /// have one non-chain use, we only need to watch out for load/op/store @@ -1336,11 +1352,17 @@ static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse) { return findNonImmUse(Root, Def, ImmedUse, Root, Visited); } -/// IsLegalAndProfitableToFold - Returns true if the specific operand node N of -/// U can be folded during instruction selection that starts at Root and -/// folding N is profitable. -bool SelectionDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U, - SDNode *Root) const { +/// IsProfitableToFold - Returns true if it's profitable to fold the specific +/// operand node N of U during instruction selection that starts at Root. +bool SelectionDAGISel::IsProfitableToFold(SDValue N, SDNode *U, + SDNode *Root) const { + if (OptLevel == CodeGenOpt::None) return false; + return N.hasOneUse(); +} + +/// IsLegalToFold - Returns true if the specific operand node N of +/// U can be folded during instruction selection that starts at Root. +bool SelectionDAGISel::IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const { if (OptLevel == CodeGenOpt::None) return false; // If Root use can somehow reach N through a path that that doesn't contain @@ -1394,7 +1416,7 @@ bool SelectionDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U, VT = Root->getValueType(Root->getNumValues()-1); } - return !isNonImmUse(Root, N, U); + return !isNonImmUse(Root, N.getNode(), U); } SDNode *SelectionDAGISel::Select_INLINEASM(SDNode *N) { @@ -1410,15 +1432,14 @@ SDNode *SelectionDAGISel::Select_INLINEASM(SDNode *N) { } SDNode *SelectionDAGISel::Select_UNDEF(SDNode *N) { - return CurDAG->SelectNodeTo(N, TargetInstrInfo::IMPLICIT_DEF, - N->getValueType(0)); + return CurDAG->SelectNodeTo(N, TargetOpcode::IMPLICIT_DEF,N->getValueType(0)); } SDNode *SelectionDAGISel::Select_EH_LABEL(SDNode *N) { SDValue Chain = N->getOperand(0); unsigned C = cast<LabelSDNode>(N)->getLabelID(); SDValue Tmp = CurDAG->getTargetConstant(C, MVT::i32); - return CurDAG->SelectNodeTo(N, TargetInstrInfo::EH_LABEL, + return CurDAG->SelectNodeTo(N, TargetOpcode::EH_LABEL, MVT::Other, Tmp, Chain); } diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 81c51c49b720d..e88af4f3e02c1 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -13,6 +13,7 @@ #include "llvm/Target/TargetLowering.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCExpr.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" @@ -21,6 +22,8 @@ #include "llvm/GlobalVariable.h" #include "llvm/DerivedTypes.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/ErrorHandling.h" @@ -507,7 +510,6 @@ TargetLowering::TargetLowering(TargetMachine &tm,TargetLoweringObjectFile *tlof) setOperationAction(ISD::TRAP, MVT::Other, Expand); IsLittleEndian = TD->isLittleEndian(); - UsesGlobalOffsetTable = false; ShiftAmountTy = PointerTy = MVT::getIntegerVT(8*TD->getPointerSize()); memset(RegClassForVT, 0,MVT::LAST_VALUETYPE*sizeof(TargetRegisterClass*)); memset(TargetDAGCombineArray, 0, array_lengthof(TargetDAGCombineArray)); @@ -538,6 +540,24 @@ TargetLowering::~TargetLowering() { delete &TLOF; } +/// canOpTrap - Returns true if the operation can trap for the value type. +/// VT must be a legal type. +bool TargetLowering::canOpTrap(unsigned Op, EVT VT) const { + assert(isTypeLegal(VT)); + switch (Op) { + default: + return false; + case ISD::FDIV: + case ISD::FREM: + case ISD::SDIV: + case ISD::UDIV: + case ISD::SREM: + case ISD::UREM: + return true; + } +} + + static unsigned getVectorTypeBreakdownMVT(MVT VT, MVT &IntermediateVT, unsigned &NumIntermediates, EVT &RegisterVT, @@ -682,7 +702,7 @@ void TargetLowering::computeRegisterProperties() { for (unsigned nVT = i+1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) { EVT SVT = (MVT::SimpleValueType)nVT; if (isTypeLegal(SVT) && SVT.getVectorElementType() == EltVT && - SVT.getVectorNumElements() > NElts) { + SVT.getVectorNumElements() > NElts && NElts != 1) { TransformToType[i] = SVT; ValueTypeActions.setTypeAction(VT, Promote); IsLegalWiderType = true; @@ -793,13 +813,40 @@ unsigned TargetLowering::getByValTypeAlignment(const Type *Ty) const { return TD->getCallFrameTypeAlignment(Ty); } +/// getJumpTableEncoding - Return the entry encoding for a jump table in the +/// current function. The returned value is a member of the +/// MachineJumpTableInfo::JTEntryKind enum. +unsigned TargetLowering::getJumpTableEncoding() const { + // In non-pic modes, just use the address of a block. + if (getTargetMachine().getRelocationModel() != Reloc::PIC_) + return MachineJumpTableInfo::EK_BlockAddress; + + // In PIC mode, if the target supports a GPRel32 directive, use it. + if (getTargetMachine().getMCAsmInfo()->getGPRel32Directive() != 0) + return MachineJumpTableInfo::EK_GPRel32BlockAddress; + + // Otherwise, use a label difference. + return MachineJumpTableInfo::EK_LabelDifference32; +} + SDValue TargetLowering::getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const { - if (usesGlobalOffsetTable()) + // If our PIC model is GP relative, use the global offset table as the base. + if (getJumpTableEncoding() == MachineJumpTableInfo::EK_GPRel32BlockAddress) return DAG.getGLOBAL_OFFSET_TABLE(getPointerTy()); return Table; } +/// getPICJumpTableRelocBaseExpr - This returns the relocation base for the +/// given PIC jumptable, the same as getPICJumpTableRelocBase, but as an +/// MCExpr. +const MCExpr * +TargetLowering::getPICJumpTableRelocBaseExpr(const MachineFunction *MF, + unsigned JTI,MCContext &Ctx) const{ + // The normal PIC reloc base is the label at the start of the jump table. + return MCSymbolRefExpr::Create(MF->getJTISymbol(JTI, Ctx), Ctx); +} + bool TargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { // Assume that everything is safe in static mode. @@ -1669,7 +1716,7 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1, SDValue NewLoad = DAG.getLoad(newVT, dl, Lod->getChain(), Ptr, Lod->getSrcValue(), Lod->getSrcValueOffset() + bestOffset, - false, NewAlign); + false, false, NewAlign); return DAG.getSetCC(dl, VT, DAG.getNode(ISD::AND, dl, newVT, NewLoad, DAG.getConstant(bestMask.trunc(bestWidth), @@ -2337,7 +2384,7 @@ getRegForInlineAsmConstraint(const std::string &Constraint, E = RI->regclass_end(); RCI != E; ++RCI) { const TargetRegisterClass *RC = *RCI; - // If none of the the value types for this register class are valid, we + // If none of the value types for this register class are valid, we // can't use it. For example, 64-bit reg classes on 32-bit targets. bool isLegal = false; for (TargetRegisterClass::vt_iterator I = RC->vt_begin(), E = RC->vt_end(); |