diff options
author | Eric Christopher <echristo@apple.com> | 2010-03-05 06:58:57 +0000 |
---|---|---|
committer | Eric Christopher <echristo@apple.com> | 2010-03-05 06:58:57 +0000 |
commit | 25ec483cfca8d3a3ba8728a4a126e04b92789069 (patch) | |
tree | b669dec328eb3bbee9e93aaf46db0828394b891f /lib/Transforms/Scalar | |
parent | b71a2fcf5e5c0e4b598f07f5e3e7b0f2c718baf2 (diff) | |
download | external_llvm-25ec483cfca8d3a3ba8728a4a126e04b92789069.zip external_llvm-25ec483cfca8d3a3ba8728a4a126e04b92789069.tar.gz external_llvm-25ec483cfca8d3a3ba8728a4a126e04b92789069.tar.bz2 |
Move GetStringLength and helper from SimplifyLibCalls to ValueTracking.
No functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97793 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r-- | lib/Transforms/Scalar/SimplifyLibCalls.cpp | 124 |
1 files changed, 0 insertions, 124 deletions
diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp index cde214b..5eae7b3 100644 --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -433,130 +433,6 @@ void LibCallOptimization::EmitFWrite(Value *Ptr, Value *Size, Value *File, // Helper Functions //===----------------------------------------------------------------------===// -/// GetStringLengthH - If we can compute the length of the string pointed to by -/// the specified pointer, return 'len+1'. If we can't, return 0. -static uint64_t GetStringLengthH(Value *V, SmallPtrSet<PHINode*, 32> &PHIs) { - // Look through noop bitcast instructions. - if (BitCastInst *BCI = dyn_cast<BitCastInst>(V)) - return GetStringLengthH(BCI->getOperand(0), PHIs); - - // If this is a PHI node, there are two cases: either we have already seen it - // or we haven't. - if (PHINode *PN = dyn_cast<PHINode>(V)) { - if (!PHIs.insert(PN)) - return ~0ULL; // already in the set. - - // If it was new, see if all the input strings are the same length. - uint64_t LenSoFar = ~0ULL; - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { - uint64_t Len = GetStringLengthH(PN->getIncomingValue(i), PHIs); - if (Len == 0) return 0; // Unknown length -> unknown. - - if (Len == ~0ULL) continue; - - if (Len != LenSoFar && LenSoFar != ~0ULL) - return 0; // Disagree -> unknown. - LenSoFar = Len; - } - - // Success, all agree. - return LenSoFar; - } - - // strlen(select(c,x,y)) -> strlen(x) ^ strlen(y) - if (SelectInst *SI = dyn_cast<SelectInst>(V)) { - uint64_t Len1 = GetStringLengthH(SI->getTrueValue(), PHIs); - if (Len1 == 0) return 0; - uint64_t Len2 = GetStringLengthH(SI->getFalseValue(), PHIs); - if (Len2 == 0) return 0; - if (Len1 == ~0ULL) return Len2; - if (Len2 == ~0ULL) return Len1; - if (Len1 != Len2) return 0; - return Len1; - } - - // If the value is not a GEP instruction nor a constant expression with a - // GEP instruction, then return unknown. - User *GEP = 0; - if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) { - GEP = GEPI; - } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { - if (CE->getOpcode() != Instruction::GetElementPtr) - return 0; - GEP = CE; - } else { - return 0; - } - - // Make sure the GEP has exactly three arguments. - if (GEP->getNumOperands() != 3) - return 0; - - // Check to make sure that the first operand of the GEP is an integer and - // has value 0 so that we are sure we're indexing into the initializer. - if (ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand(1))) { - if (!Idx->isZero()) - return 0; - } else - return 0; - - // If the second index isn't a ConstantInt, then this is a variable index - // into the array. If this occurs, we can't say anything meaningful about - // the string. - uint64_t StartIdx = 0; - if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2))) - StartIdx = CI->getZExtValue(); - else - return 0; - - // The GEP instruction, constant or instruction, must reference a global - // variable that is a constant and is initialized. The referenced constant - // initializer is the array that we'll use for optimization. - GlobalVariable* GV = dyn_cast<GlobalVariable>(GEP->getOperand(0)); - if (!GV || !GV->isConstant() || !GV->hasInitializer() || - GV->mayBeOverridden()) - return 0; - Constant *GlobalInit = GV->getInitializer(); - - // Handle the ConstantAggregateZero case, which is a degenerate case. The - // initializer is constant zero so the length of the string must be zero. - if (isa<ConstantAggregateZero>(GlobalInit)) - return 1; // Len = 0 offset by 1. - - // Must be a Constant Array - ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit); - if (!Array || !Array->getType()->getElementType()->isIntegerTy(8)) - return false; - - // Get the number of elements in the array - uint64_t NumElts = Array->getType()->getNumElements(); - - // Traverse the constant array from StartIdx (derived above) which is - // the place the GEP refers to in the array. - for (unsigned i = StartIdx; i != NumElts; ++i) { - Constant *Elt = Array->getOperand(i); - ConstantInt *CI = dyn_cast<ConstantInt>(Elt); - if (!CI) // This array isn't suitable, non-int initializer. - return 0; - if (CI->isZero()) - return i-StartIdx+1; // We found end of string, success! - } - - return 0; // The array isn't null terminated, conservatively return 'unknown'. -} - -/// GetStringLength - If we can compute the length of the string pointed to by -/// the specified pointer, return 'len+1'. If we can't, return 0. -static uint64_t GetStringLength(Value *V) { - if (!V->getType()->isPointerTy()) return 0; - - SmallPtrSet<PHINode*, 32> PHIs; - uint64_t Len = GetStringLengthH(V, PHIs); - // If Len is ~0ULL, we had an infinite phi cycle: this is dead code, so return - // an empty string as a length. - return Len == ~0ULL ? 1 : Len; -} - /// IsOnlyUsedInZeroEqualityComparison - Return true if it only matters that the /// value is equal or not-equal to zero. static bool IsOnlyUsedInZeroEqualityComparison(Value *V) { |