Changes in directory llvm/lib/CodeGen/SelectionDAG:
SelectionDAGISel.cpp updated: 1.93 -> 1.94 --- Log message: Handle GEP's a bit more intelligently. Fold constant indices early and turn power-of-two multiplies into shifts early to improve compile time. --- Diffs of the changes: (+39 -15) SelectionDAGISel.cpp | 54 ++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 39 insertions(+), 15 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.93 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.94 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.93 Sun Nov 6 03:00:38 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Nov 8 22:45:33 2005 @@ -32,6 +32,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/Debug.h" #include <map> #include <iostream> @@ -607,24 +608,47 @@ Ty = StTy->getElementType(Field); } else { Ty = cast<SequentialType>(Ty)->getElementType(); - if (!isa<Constant>(Idx) || !cast<Constant>(Idx)->isNullValue()) { - // N = N + Idx * ElementSize; - uint64_t ElementSize = TD.getTypeSize(Ty); - SDOperand IdxN = getValue(Idx), Scale = getIntPtrConstant(ElementSize); - - // If the index is smaller or larger than intptr_t, truncate or extend - // it. - if (IdxN.getValueType() < Scale.getValueType()) { - if (Idx->getType()->isSigned()) - IdxN = DAG.getNode(ISD::SIGN_EXTEND, Scale.getValueType(), IdxN); - else - IdxN = DAG.getNode(ISD::ZERO_EXTEND, Scale.getValueType(), IdxN); - } else if (IdxN.getValueType() > Scale.getValueType()) - IdxN = DAG.getNode(ISD::TRUNCATE, Scale.getValueType(), IdxN); - IdxN = DAG.getNode(ISD::MUL, N.getValueType(), IdxN, Scale); + // If this is a constant subscript, handle it quickly. + if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx)) { + if (CI->getRawValue() == 0) continue; + + uint64_t Offs; + if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(CI)) + Offs = (int64_t)TD.getTypeSize(Ty)*CSI->getValue(); + else + Offs = TD.getTypeSize(Ty)*cast<ConstantUInt>(CI)->getValue(); + N = DAG.getNode(ISD::ADD, N.getValueType(), N, getIntPtrConstant(Offs)); + continue; + } + + // N = N + Idx * ElementSize; + uint64_t ElementSize = TD.getTypeSize(Ty); + SDOperand IdxN = getValue(Idx); + + // If the index is smaller or larger than intptr_t, truncate or extend + // it. + if (IdxN.getValueType() < N.getValueType()) { + if (Idx->getType()->isSigned()) + IdxN = DAG.getNode(ISD::SIGN_EXTEND, N.getValueType(), IdxN); + else + IdxN = DAG.getNode(ISD::ZERO_EXTEND, N.getValueType(), IdxN); + } else if (IdxN.getValueType() > N.getValueType()) + IdxN = DAG.getNode(ISD::TRUNCATE, N.getValueType(), IdxN); + + // If this is a multiply by a power of two, turn it into a shl + // immediately. This is a very common case. + if (isPowerOf2_64(ElementSize)) { + unsigned Amt = Log2_64(ElementSize); + IdxN = DAG.getNode(ISD::SHL, N.getValueType(), IdxN, + getIntPtrConstant(Amt)); N = DAG.getNode(ISD::ADD, N.getValueType(), N, IdxN); + continue; } + + SDOperand Scale = getIntPtrConstant(ElementSize); + IdxN = DAG.getNode(ISD::MUL, N.getValueType(), IdxN, Scale); + N = DAG.getNode(ISD::ADD, N.getValueType(), N, IdxN); } } setValue(&I, N); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits