[llvm-commits] [llvm] r118904 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Evan Cheng evan.cheng at apple.com
Fri Nov 12 10:44:17 PST 2010


Nice. Thanks Andy.

Evan
On Nov 12, 2010, at 9:50 AM, Andrew Trick wrote:

> Author: atrick
> Date: Fri Nov 12 11:50:46 2010
> New Revision: 118904
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=118904&view=rev
> Log:
> Fixes PR8287: SD scheduling time. The fix is a failsafe that prevents
> catastrophic compilation time in the event of unreasonable LLVM
> IR. Code quality is a separate issue--someone upstream needs to do a
> better job of reducing to llvm.memcpy. If the situation can be reproduced with
> any supported frontend, then it will be a separate bug.
> 
> Modified:
>    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> 
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=118904&r1=118903&r2=118904&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Fri Nov 12 11:50:46 2010
> @@ -71,6 +71,21 @@
>                  cl::location(LimitFloatPrecision),
>                  cl::init(0));
> 
> +// Limit the width of DAG chains. This is important in general to prevent
> +// prevent DAG-based analysis from blowing up. For example, alias analysis and
> +// load clustering may not complete in reasonable time. It is difficult to
> +// recognize and avoid this situation within each individual analysis, and
> +// future analyses are likely to have the same behavior. Limiting DAG width is
> +// the safe approach, and will be especially important with global DAGs. See
> +// 2010-11-11-ReturnBigBuffer.ll.
> +//
> +// MaxParallelChains default is arbitrarily high to avoid affecting
> +// optimization, but could be lowered to improve compile time. Any ld-ld-st-st
> +// sequence over this should have been converted to llvm.memcpy by the fronend.
> +static cl::opt<unsigned>
> +MaxParallelChains("dag-chain-limit", cl::desc("Max parallel isel dag chains"),
> +                  cl::init(64), cl::Hidden);
> +
> static SDValue getCopyFromPartsVector(SelectionDAG &DAG, DebugLoc DL,
>                                       const SDValue *Parts, unsigned NumParts,
>                                       EVT PartVT, EVT ValueVT);
> @@ -2945,7 +2960,7 @@
> 
>   SDValue Root;
>   bool ConstantMemory = false;
> -  if (I.isVolatile())
> +  if (I.isVolatile() || NumValues > MaxParallelChains)
>     // Serialize volatile loads with other side effects.
>     Root = getRoot();
>   else if (AA->pointsToConstantMemory(
> @@ -2957,11 +2972,26 @@
>     // Do not serialize non-volatile loads against each other.
>     Root = DAG.getRoot();
>   }
> -
> +  
>   SmallVector<SDValue, 4> Values(NumValues);
> -  SmallVector<SDValue, 4> Chains(NumValues);
> +  SmallVector<SDValue, 4> Chains(std::min(unsigned(MaxParallelChains),
> +                                          NumValues));
>   EVT PtrVT = Ptr.getValueType();
> -  for (unsigned i = 0; i != NumValues; ++i) {
> +  unsigned ChainI = 0;
> +  for (unsigned i = 0; i != NumValues; ++i, ++ChainI) {
> +    // Serializing loads here may result in excessive register pressure, and
> +    // TokenFactor places arbitrary choke points on the scheduler. SD scheduling
> +    // could recover a bit by hoisting nodes upward in the chain by recognizing
> +    // they are side-effect free or do not alias. The optimizer should really
> +    // avoid this case by converting large object/array copies to llvm.memcpy
> +    // (MaxParallelChains should always remain as failsafe).
> +    if (ChainI == MaxParallelChains) {
> +      assert(PendingLoads.empty() && "PendingLoads must be serialized first");
> +      SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
> +                                  MVT::Other, &Chains[0], ChainI);
> +      Root = Chain;
> +      ChainI = 0;
> +    }
>     SDValue A = DAG.getNode(ISD::ADD, getCurDebugLoc(),
>                             PtrVT, Ptr,
>                             DAG.getConstant(Offsets[i], PtrVT));
> @@ -2970,12 +3000,12 @@
>                             isNonTemporal, Alignment, TBAAInfo);
> 
>     Values[i] = L;
> -    Chains[i] = L.getValue(1);
> +    Chains[ChainI] = L.getValue(1);
>   }
> 
>   if (!ConstantMemory) {
>     SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
> -                                MVT::Other, &Chains[0], NumValues);
> +                                MVT::Other, &Chains[0], ChainI);
>     if (isVolatile)
>       DAG.setRoot(Chain);
>     else
> @@ -3005,24 +3035,34 @@
>   SDValue Ptr = getValue(PtrV);
> 
>   SDValue Root = getRoot();
> -  SmallVector<SDValue, 4> Chains(NumValues);
> +  SmallVector<SDValue, 4> Chains(std::min(unsigned(MaxParallelChains),
> +                                          NumValues));
>   EVT PtrVT = Ptr.getValueType();
>   bool isVolatile = I.isVolatile();
>   bool isNonTemporal = I.getMetadata("nontemporal") != 0;
>   unsigned Alignment = I.getAlignment();
>   const MDNode *TBAAInfo = I.getMetadata(LLVMContext::MD_tbaa);
> 
> -  for (unsigned i = 0; i != NumValues; ++i) {
> +  unsigned ChainI = 0;
> +  for (unsigned i = 0; i != NumValues; ++i, ++ChainI) {
> +    // See visitLoad comments.
> +    if (ChainI == MaxParallelChains) {
> +      SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
> +                                  MVT::Other, &Chains[0], ChainI);
> +      Root = Chain;
> +      ChainI = 0;
> +    }
>     SDValue Add = DAG.getNode(ISD::ADD, getCurDebugLoc(), PtrVT, Ptr,
>                               DAG.getConstant(Offsets[i], PtrVT));
> -    Chains[i] = DAG.getStore(Root, getCurDebugLoc(),
> -                             SDValue(Src.getNode(), Src.getResNo() + i),
> -                             Add, MachinePointerInfo(PtrV, Offsets[i]),
> -                             isVolatile, isNonTemporal, Alignment, TBAAInfo);
> +    SDValue St = DAG.getStore(Root, getCurDebugLoc(),
> +                              SDValue(Src.getNode(), Src.getResNo() + i),
> +                              Add, MachinePointerInfo(PtrV, Offsets[i]),
> +                              isVolatile, isNonTemporal, Alignment, TBAAInfo);
> +    Chains[ChainI] = St;
>   }
> 
>   SDValue StoreNode = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
> -                                  MVT::Other, &Chains[0], NumValues);
> +                                  MVT::Other, &Chains[0], ChainI);
>   ++SDNodeOrder;
>   AssignOrderingToNode(StoreNode.getNode());
>   DAG.setRoot(StoreNode);
> 
> 
> _______________________________________________
> 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