[llvm-commits] [llvm] r101808 - in /llvm/trunk/lib: CodeGen/SelectionDAG/DAGCombiner.cpp Target/X86/X86ISelLowering.cpp
Evan Cheng
evan.cheng at apple.com
Wed Apr 21 14:31:09 PDT 2010
On Apr 19, 2010, at 1:55 PM, Eli Friedman wrote:
> 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?
It should be possible assuming it's done right. LegalizeType does it.
Evan
>
> -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