summaryrefslogtreecommitdiff
path: root/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-10-22 06:38:35 +0000
committerChris Lattner <sabre@nondot.org>2009-10-22 06:38:35 +0000
commit62d327e241f59735eed836e98c8f11ffaa6cf6f8 (patch)
tree2bcdf0c6b1184c775d7db64552ab8a68c78fb44e /lib/Analysis/ConstantFolding.cpp
parent878e4946700824954d7eb7f3ff660353db8e0d17 (diff)
downloadllvm-62d327e241f59735eed836e98c8f11ffaa6cf6f8.tar.gz
llvm-62d327e241f59735eed836e98c8f11ffaa6cf6f8.tar.bz2
llvm-62d327e241f59735eed836e98c8f11ffaa6cf6f8.tar.xz
move 'loading i32 from string' optimization from instcombine
to libanalysis. Instcombine shrinking... does this even make sense??? git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84840 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ConstantFolding.cpp')
-rw-r--r--lib/Analysis/ConstantFolding.cpp41
1 files changed, 35 insertions, 6 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index da671c8f5d..1f91ddf378 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -24,13 +24,13 @@
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/LLVMContext.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/Target/TargetData.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/Target/TargetData.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/GlobalVariable.h"
#include <cerrno>
#include <cmath>
using namespace llvm;
@@ -111,6 +111,35 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C,
ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE))
return V;
}
+
+ // Instead of loading constant c string, use corresponding integer value
+ // directly if string length is small enough.
+ std::string Str;
+ if (TD && GetConstantStringInfo(CE->getOperand(0), Str) && !Str.empty()) {
+ unsigned len = Str.length();
+ const Type *Ty = cast<PointerType>(CE->getType())->getElementType();
+ unsigned numBits = Ty->getPrimitiveSizeInBits();
+ // Replace LI with immediate integer store.
+ if ((numBits >> 3) == len + 1) {
+ APInt StrVal(numBits, 0);
+ APInt SingleChar(numBits, 0);
+ if (TD->isLittleEndian()) {
+ for (signed i = len-1; i >= 0; i--) {
+ SingleChar = (uint64_t) Str[i] & UCHAR_MAX;
+ StrVal = (StrVal << 8) | SingleChar;
+ }
+ } else {
+ for (unsigned i = 0; i < len; i++) {
+ SingleChar = (uint64_t) Str[i] & UCHAR_MAX;
+ StrVal = (StrVal << 8) | SingleChar;
+ }
+ // Append NULL at the end.
+ SingleChar = 0;
+ StrVal = (StrVal << 8) | SingleChar;
+ }
+ return ConstantInt::get(CE->getContext(), StrVal);
+ }
+ }
}
return 0;
@@ -675,15 +704,15 @@ Constant *llvm::ConstantFoldLoadThroughGEPConstantExpr(Constant *C,
C = UndefValue::get(ATy->getElementType());
else
return 0;
- } else if (const VectorType *PTy = dyn_cast<VectorType>(*I)) {
- if (CI->getZExtValue() >= PTy->getNumElements())
+ } else if (const VectorType *VTy = dyn_cast<VectorType>(*I)) {
+ if (CI->getZExtValue() >= VTy->getNumElements())
return 0;
if (ConstantVector *CP = dyn_cast<ConstantVector>(C))
C = CP->getOperand(CI->getZExtValue());
else if (isa<ConstantAggregateZero>(C))
- C = Constant::getNullValue(PTy->getElementType());
+ C = Constant::getNullValue(VTy->getElementType());
else if (isa<UndefValue>(C))
- C = UndefValue::get(PTy->getElementType());
+ C = UndefValue::get(VTy->getElementType());
else
return 0;
} else {