aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-11-09 04:45:33 +0000
committerChris Lattner <sabre@nondot.org>2005-11-09 04:45:33 +0000
commit7c0104b525a4ba8b5268ee5455f92b011f7cc263 (patch)
treeb63561ed6327bb9ae443f17c4e0e974e0053ac64 /lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
parent0d902a9c740bdaa57396547f26a02c234752c579 (diff)
Handle GEP's a bit more intelligently. Fold constant indices early and
turn power-of-two multiplies into shifts early to improve compile time. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24253 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp56
1 files changed, 40 insertions, 16 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 64256c963e..ab176c1f61 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -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 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) {
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);