[llvm-commits] [llvm] r101808 - in /llvm/trunk/lib: CodeGen/SelectionDAG/DAGCombiner.cpp Target/X86/X86ISelLowering.cpp
Eli Friedman
eli.friedman at gmail.com
Mon Apr 19 13:55:23 PDT 2010
On Mon, Apr 19, 2010 at 12:29 PM, Evan Cheng <evan.cheng at apple.com> wrote:
> Author: evancheng
> Date: Mon Apr 19 14:29:22 2010
> New Revision: 101808
>
> URL: http://llvm.org/viewvc/llvm-project?rev=101808&view=rev
> Log:
> More progress on promoting i16 operations to i32 for x86. Work in progress.
Is it really correct to try and promote a rotate? Won't that change the result?
-Eli
> Modified:
> llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=101808&r1=101807&r2=101808&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Apr 19 14:29:22 2010
> @@ -130,6 +130,8 @@
> bool CombineToPostIndexedLoadStore(SDNode *N);
>
> SDValue PromoteIntBinOp(SDValue Op);
> + SDValue PromoteExtend(SDValue Op);
> + bool PromoteLoad(SDValue Op);
>
> /// combine - call the node-specific routine that knows how to fold each
> /// particular type of node. If that doesn't do anything, try the
> @@ -167,6 +169,8 @@
> SDValue visitSHL(SDNode *N);
> SDValue visitSRA(SDNode *N);
> SDValue visitSRL(SDNode *N);
> + SDValue visitROTL(SDNode *N);
> + SDValue visitROTR(SDNode *N);
> SDValue visitCTLZ(SDNode *N);
> SDValue visitCTTZ(SDNode *N);
> SDValue visitCTPOP(SDNode *N);
> @@ -633,25 +637,44 @@
> return true;
> }
>
> +static SDValue SExtPromoteOperand(SDValue Op, EVT PVT, SelectionDAG &DAG,
> + const TargetLowering &TLI);
> +static SDValue ZExtPromoteOperand(SDValue Op, EVT PVT, SelectionDAG &DAG,
> + const TargetLowering &TLI);
> +
> static SDValue PromoteOperand(SDValue Op, EVT PVT, SelectionDAG &DAG,
> const TargetLowering &TLI) {
> + DebugLoc dl = Op.getDebugLoc();
> if (LoadSDNode *LD = dyn_cast<LoadSDNode>(Op)) {
> - return DAG.getExtLoad(ISD::EXTLOAD, Op.getDebugLoc(), PVT,
> + ISD::LoadExtType ExtType =
> + ISD::isNON_EXTLoad(LD) ? ISD::EXTLOAD : LD->getExtensionType();
> + return DAG.getExtLoad(ExtType, dl, PVT,
> LD->getChain(), LD->getBasePtr(),
> LD->getSrcValue(), LD->getSrcValueOffset(),
> LD->getMemoryVT(), LD->isVolatile(),
> LD->isNonTemporal(), LD->getAlignment());
> }
>
> - unsigned Opc = ISD::ANY_EXTEND;
> - if (Op.getOpcode() == ISD::Constant)
> + unsigned Opc = Op.getOpcode();
> + if (Opc == ISD::AssertSext)
> + return DAG.getNode(ISD::AssertSext, dl, PVT,
> + SExtPromoteOperand(Op.getOperand(0), PVT, DAG, TLI),
> + Op.getOperand(1));
> + else if (Opc == ISD::AssertZext)
> + return DAG.getNode(ISD::AssertZext, dl, PVT,
> + ZExtPromoteOperand(Op.getOperand(0), PVT, DAG, TLI),
> + Op.getOperand(1));
> +
> + unsigned ExtOpc = ISD::ANY_EXTEND;
> + if (Opc == ISD::Constant)
> // Zero extend things like i1, sign extend everything else. It shouldn't
> // matter in theory which one we pick, but this tends to give better code?
> // See DAGTypeLegalizer::PromoteIntRes_Constant.
> - Opc = Op.getValueType().isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
> - if (!TLI.isOperationLegal(Opc, PVT))
> + ExtOpc =
> + Op.getValueType().isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
> + if (!TLI.isOperationLegal(ExtOpc, PVT))
> return SDValue();
> - return DAG.getNode(Opc, Op.getDebugLoc(), PVT, Op);
> + return DAG.getNode(ExtOpc, dl, PVT, Op);
> }
>
> static SDValue SExtPromoteOperand(SDValue Op, EVT PVT, SelectionDAG &DAG,
> @@ -727,6 +750,80 @@
> return SDValue();
> }
>
> +SDValue DAGCombiner::PromoteExtend(SDValue Op) {
> + if (!LegalOperations)
> + return SDValue();
> +
> + EVT VT = Op.getValueType();
> + if (VT.isVector() || !VT.isInteger())
> + return SDValue();
> +
> + // If operation type is 'undesirable', e.g. i16 on x86, consider
> + // promoting it.
> + unsigned Opc = Op.getOpcode();
> + if (TLI.isTypeDesirableForOp(Opc, VT))
> + return SDValue();
> +
> + EVT PVT = VT;
> + // Consult target whether it is a good idea to promote this operation and
> + // what's the right type to promote it to.
> + if (TLI.IsDesirableToPromoteOp(Op, PVT)) {
> + assert(PVT != VT && "Don't know what type to promote to!");
> + // fold (aext (aext x)) -> (aext x)
> + // fold (aext (zext x)) -> (zext x)
> + // fold (aext (sext x)) -> (sext x)
> + return DAG.getNode(Op.getOpcode(), Op.getDebugLoc(), VT, Op.getOperand(0));
> + }
> + return SDValue();
> +}
> +
> +bool DAGCombiner::PromoteLoad(SDValue Op) {
> + if (!LegalOperations)
> + return false;
> +
> + EVT VT = Op.getValueType();
> + if (VT.isVector() || !VT.isInteger())
> + return false;
> +
> + // If operation type is 'undesirable', e.g. i16 on x86, consider
> + // promoting it.
> + unsigned Opc = Op.getOpcode();
> + if (TLI.isTypeDesirableForOp(Opc, VT))
> + return false;
> +
> + EVT PVT = VT;
> + // Consult target whether it is a good idea to promote this operation and
> + // what's the right type to promote it to.
> + if (TLI.IsDesirableToPromoteOp(Op, PVT)) {
> + assert(PVT != VT && "Don't know what type to promote to!");
> +
> + DebugLoc dl = Op.getDebugLoc();
> + SDNode *N = Op.getNode();
> + LoadSDNode *LD = cast<LoadSDNode>(N);
> + ISD::LoadExtType ExtType =
> + ISD::isNON_EXTLoad(LD) ? ISD::EXTLOAD : LD->getExtensionType();
> + SDValue NewLD = DAG.getExtLoad(ExtType, dl, PVT,
> + LD->getChain(), LD->getBasePtr(),
> + LD->getSrcValue(), LD->getSrcValueOffset(),
> + LD->getMemoryVT(), LD->isVolatile(),
> + LD->isNonTemporal(), LD->getAlignment());
> + SDValue Result = DAG.getNode(ISD::TRUNCATE, dl, VT, NewLD);
> +
> + DEBUG(dbgs() << "\nReplacing.x ";
> + N->dump(&DAG);
> + dbgs() << "\nWith: ";
> + Result.getNode()->dump(&DAG);
> + dbgs() << '\n');
> + WorkListRemover DeadNodes(*this);
> + DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Result, &DeadNodes);
> + DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), NewLD.getValue(1), &DeadNodes);
> + removeFromWorkList(N);
> + DAG.DeleteNode(N);
> + return true;
> + }
> + return false;
> +}
> +
>
> //===----------------------------------------------------------------------===//
> // Main DAG Combiner implementation
> @@ -856,6 +953,8 @@
> case ISD::SHL: return visitSHL(N);
> case ISD::SRA: return visitSRA(N);
> case ISD::SRL: return visitSRL(N);
> + case ISD::ROTL: return visitROTL(N);
> + case ISD::ROTR: return visitROTR(N);
> case ISD::CTLZ: return visitCTLZ(N);
> case ISD::CTTZ: return visitCTTZ(N);
> case ISD::CTPOP: return visitCTPOP(N);
> @@ -2975,6 +3074,14 @@
> return PromoteIntBinOp(SDValue(N, 0));
> }
>
> +SDValue DAGCombiner::visitROTL(SDNode *N) {
> + return PromoteIntBinOp(SDValue(N, 0));
> +}
> +
> +SDValue DAGCombiner::visitROTR(SDNode *N) {
> + return PromoteIntBinOp(SDValue(N, 0));
> +}
> +
> SDValue DAGCombiner::visitCTLZ(SDNode *N) {
> SDValue N0 = N->getOperand(0);
> EVT VT = N->getValueType(0);
> @@ -3369,7 +3476,7 @@
> DAG.SignBitIsZero(N0))
> return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, N0);
>
> - return SDValue();
> + return PromoteExtend(SDValue(N, 0));
> }
>
> SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
> @@ -3532,7 +3639,7 @@
> N0.getOperand(1)));
> }
>
> - return SDValue();
> + return PromoteExtend(SDValue(N, 0));
> }
>
> SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
> @@ -3668,7 +3775,7 @@
> return SCC;
> }
>
> - return SDValue();
> + return PromoteExtend(SDValue(N, 0));
> }
>
> /// GetDemandedBits - See if the specified operand can be simplified with the
> @@ -5270,6 +5377,8 @@
> if (CombineToPreIndexedLoadStore(N) || CombineToPostIndexedLoadStore(N))
> return SDValue(N, 0);
>
> + if (PromoteLoad(SDValue(N, 0)))
> + return SDValue(N, 0);
> return SDValue();
> }
>
>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=101808&r1=101807&r2=101808&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Apr 19 14:29:22 2010
> @@ -9966,9 +9966,15 @@
> switch (Opc) {
> default:
> return true;
> + case ISD::LOAD:
> + case ISD::SIGN_EXTEND:
> + case ISD::ZERO_EXTEND:
> + case ISD::ANY_EXTEND:
> case ISD::SHL:
> case ISD::SRA:
> case ISD::SRL:
> + case ISD::ROTL:
> + case ISD::ROTR:
> case ISD::SUB:
> case ISD::ADD:
> case ISD::MUL:
> @@ -9990,27 +9996,47 @@
> if (VT != MVT::i16)
> return false;
>
> - bool Commute = true;
> + bool Promote = false;
> + bool Commute = false;
> switch (Op.getOpcode()) {
> - default: return false;
> + default: break;
> + case ISD::LOAD: {
> + LoadSDNode *LD = cast<LoadSDNode>(Op);
> + // If the non-extending load has a single use and it's not live out, then it
> + // might be folded.
> + if (LD->getExtensionType() == ISD::NON_EXTLOAD &&
> + Op.hasOneUse() &&
> + Op.getNode()->use_begin()->getOpcode() != ISD::CopyToReg)
> + return false;
> + Promote = true;
> + break;
> + }
> + case ISD::SIGN_EXTEND:
> + case ISD::ZERO_EXTEND:
> + case ISD::ANY_EXTEND:
> + Promote = true;
> + break;
> case ISD::SHL:
> case ISD::SRA:
> - case ISD::SRL: {
> + case ISD::SRL:
> + case ISD::ROTL:
> + case ISD::ROTR: {
> SDValue N0 = Op.getOperand(0);
> // Look out for (store (shl (load), x)).
> if (isa<LoadSDNode>(N0) && N0.hasOneUse() &&
> Op.hasOneUse() && Op.getNode()->use_begin()->getOpcode() == ISD::STORE)
> return false;
> + Promote = true;
> break;
> }
> - case ISD::SUB:
> - Commute = false;
> - // fallthrough
> case ISD::ADD:
> case ISD::MUL:
> case ISD::AND:
> case ISD::OR:
> - case ISD::XOR: {
> + case ISD::XOR:
> + Commute = true;
> + // fallthrough
> + case ISD::SUB: {
> SDValue N0 = Op.getOperand(0);
> SDValue N1 = Op.getOperand(1);
> if (!Commute && isa<LoadSDNode>(N1))
> @@ -10020,11 +10046,12 @@
> return false;
> if ((isa<LoadSDNode>(N1) && N1.hasOneUse()) && !isa<ConstantSDNode>(N0))
> return false;
> + Promote = true;
> }
> }
>
> PVT = MVT::i32;
> - return true;
> + return Promote;
> }
>
> //===----------------------------------------------------------------------===//
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list