diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2008-06-29 17:57:03 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2008-06-29 17:57:03 +0000 |
commit | 6d116bc7ced56a820d33b0dd35ee36af8a810eab (patch) | |
tree | b9d056c655001ef42c66a3395d01233d2a499537 /lib | |
parent | 28a2b54580b28be10c536def7f49b5599adf3631 (diff) | |
download | external_llvm-6d116bc7ced56a820d33b0dd35ee36af8a810eab.zip external_llvm-6d116bc7ced56a820d33b0dd35ee36af8a810eab.tar.gz external_llvm-6d116bc7ced56a820d33b0dd35ee36af8a810eab.tar.bz2 |
Revert (52748 and friends):
Move GetConstantStringInfo to lib/Analysis. Remove
string output routine from Constant. Update all
callers. Change debug intrinsic api slightly to
accomodate move of routine, these now return values
instead of strings.
This unbreaks llvm-gcc bootstrap.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52884 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/ValueTracking.cpp | 100 | ||||
-rw-r--r-- | lib/CodeGen/MachineModuleInfo.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 20 | ||||
-rw-r--r-- | lib/Debugger/ProgramInfo.cpp | 10 | ||||
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 4 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SimplifyLibCalls.cpp | 83 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 42 | ||||
-rw-r--r-- | lib/VMCore/IntrinsicInst.cpp | 13 |
8 files changed, 148 insertions, 129 deletions
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index e7e291f..32a77e6 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -15,7 +15,6 @@ #include "llvm/Analysis/ValueTracking.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" -#include "llvm/GlobalVariable.h" #include "llvm/IntrinsicInst.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/GetElementPtrTypeIterator.h" @@ -931,102 +930,3 @@ Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin, // or load instruction) return 0; } - -/// GetConstantStringInfo - This function computes the length of a -/// null-terminated C string pointed to by V. If successful, it returns true -/// and returns the string in Str. If unsuccessful, it returns false. -bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset, - bool StopAtNul) { - // If V is NULL then return false; - if (V == NULL) return false; - - // Look through bitcast instructions. - if (BitCastInst *BCI = dyn_cast<BitCastInst>(V)) - return GetConstantStringInfo(BCI->getOperand(0), Str, Offset, StopAtNul); - - // If the value is not a GEP instruction nor a constant expression with a - // GEP instruction, then return false because ConstantArray can't occur - // any other way - User *GEP = 0; - if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) { - GEP = GEPI; - } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { - if (CE->getOpcode() == Instruction::BitCast) - return GetConstantStringInfo(CE->getOperand(0), Str, Offset, StopAtNul); - if (CE->getOpcode() != Instruction::GetElementPtr) - return false; - GEP = CE; - } - - if (GEP) { - // Make sure the GEP has exactly three arguments. - if (GEP->getNumOperands() != 3) - return false; - - // Make sure the index-ee is a pointer to array of i8. - const PointerType *PT = cast<PointerType>(GEP->getOperand(0)->getType()); - const ArrayType *AT = dyn_cast<ArrayType>(PT->getElementType()); - if (AT == 0 || AT->getElementType() != Type::Int8Ty) - return false; - - // 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. - ConstantInt *FirstIdx = dyn_cast<ConstantInt>(GEP->getOperand(1)); - if (FirstIdx == 0 || !FirstIdx->isZero()) - return false; - - // 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 false; - return GetConstantStringInfo(GEP->getOperand(0), Str, StartIdx+Offset, - StopAtNul); - } - - // 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>(V); - if (!GV || !GV->isConstant() || !GV->hasInitializer()) - return false; - Constant *GlobalInit = GV->getInitializer(); - - // Handle the ConstantAggregateZero case - if (isa<ConstantAggregateZero>(GlobalInit)) { - // This is a degenerate case. The initializer is constant zero so the - // length of the string must be zero. - Str.clear(); - return true; - } - - // Must be a Constant Array - ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit); - if (Array == 0 || Array->getType()->getElementType() != Type::Int8Ty) - return false; - - // Get the number of elements in the array - uint64_t NumElts = Array->getType()->getNumElements(); - - if (Offset > NumElts) - return false; - - // Traverse the constant array from 'Offset' which is the place the GEP refers - // to in the array. - Str.reserve(NumElts-Offset); - for (unsigned i = Offset; 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 false; - if (StopAtNul && CI->isZero()) - return true; // we found end of string, success! - Str += (char)CI->getZExtValue(); - } - - // The array isn't null terminated, but maybe this is a memcpy, not a strcpy. - return true; -} diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index 52737a6..123ad6d 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -10,7 +10,6 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/Constants.h" -#include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineLocation.h" @@ -207,9 +206,7 @@ public: } virtual void Apply(std::string &Field) { Constant *C = CI->getOperand(I++); - // Fills in the string if it succeeds - if (!GetConstantStringInfo(C, Field)) - Field.clear(); + Field = C->getStringValue(); } virtual void Apply(DebugInfoDesc *&Field) { Constant *C = CI->getOperand(I++); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 002821d..f1c2ecf 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/Constants.h" -#include "llvm/Analysis/ValueTracking.h" #include "llvm/GlobalAlias.h" #include "llvm/GlobalVariable.h" #include "llvm/Intrinsics.h" @@ -2578,7 +2577,8 @@ static SDOperand getMemBasePlusOffset(SDOperand Base, unsigned Offset, /// isMemSrcFromString - Returns true if memcpy source is a string constant. /// -static bool isMemSrcFromString(SDOperand Src, std::string &Str) { +static bool isMemSrcFromString(SDOperand Src, std::string &Str, + uint64_t &SrcOff) { unsigned SrcDelta = 0; GlobalAddressSDNode *G = NULL; if (Src.getOpcode() == ISD::GlobalAddress) @@ -2593,8 +2593,13 @@ static bool isMemSrcFromString(SDOperand Src, std::string &Str) { return false; GlobalVariable *GV = dyn_cast<GlobalVariable>(G->getGlobal()); - if (GV && GetConstantStringInfo(GV, Str, SrcDelta, false)) - return true; + if (GV && GV->isConstant()) { + Str = GV->getStringValue(false); + if (!Str.empty()) { + SrcOff += SrcDelta; + return true; + } + } return false; } @@ -2611,7 +2616,8 @@ bool MeetsMaxMemopRequirement(std::vector<MVT> &MemOps, bool AllowUnalign = TLI.allowsUnalignedMemoryAccesses(); std::string Str; - bool isSrcStr = isMemSrcFromString(Src, Str); + uint64_t SrcOff = 0; + bool isSrcStr = isMemSrcFromString(Src, Str, SrcOff); bool isSrcConst = isa<ConstantSDNode>(Src); MVT VT= TLI.getOptimalMemOpType(Size, Align, isSrcConst, isSrcStr); if (VT != MVT::iAny) { @@ -2706,11 +2712,11 @@ static SDOperand getMemcpyLoadsAndStores(SelectionDAG &DAG, return SDOperand(); std::string Str; - bool CopyFromStr = isMemSrcFromString(Src, Str); + uint64_t SrcOff = 0, DstOff = 0; + bool CopyFromStr = isMemSrcFromString(Src, Str, SrcOff); SmallVector<SDOperand, 8> OutChains; unsigned NumMemOps = MemOps.size(); - uint64_t SrcOff = 0, DstOff = 0; for (unsigned i = 0; i < NumMemOps; i++) { MVT VT = MemOps[i]; unsigned VTSize = VT.getSizeInBits() / 8; diff --git a/lib/Debugger/ProgramInfo.cpp b/lib/Debugger/ProgramInfo.cpp index 408704d..e4380ea 100644 --- a/lib/Debugger/ProgramInfo.cpp +++ b/lib/Debugger/ProgramInfo.cpp @@ -14,7 +14,6 @@ #include "llvm/Debugger/ProgramInfo.h" #include "llvm/Constants.h" -#include "llvm/Analysis/ValueTracking.h" #include "llvm/DerivedTypes.h" #include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" @@ -116,10 +115,8 @@ SourceFileInfo::SourceFileInfo(const GlobalVariable *Desc, if (ConstantInt *CUI = dyn_cast<ConstantInt>(CS->getOperand(1))) Version = CUI->getZExtValue(); - if (!GetConstantStringInfo(CS->getOperand(3), BaseName)) - BaseName = ""; - if (!GetConstantStringInfo(CS->getOperand(4), Directory)) - Directory = ""; + BaseName = CS->getOperand(3)->getStringValue(); + Directory = CS->getOperand(4)->getStringValue(); } } @@ -159,8 +156,7 @@ SourceFunctionInfo::SourceFunctionInfo(ProgramInfo &PI, SourceFile = &PI.getSourceFile(GV); // Entry #2 is the function name. - if (!GetConstantStringInfo(CS->getOperand(2), Name)) - Name = ""; + Name = CS->getOperand(2)->getStringValue(); } } diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 5d75489..d45eb99 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -9973,8 +9973,8 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI, if (ConstantExpr *CE = dyn_cast<ConstantExpr>(CI)) { // Instead of loading constant c string, use corresponding integer value // directly if string length is small enough. - std::string Str; - if (GetConstantStringInfo(CE->getOperand(0), Str) && !Str.empty()) { + const std::string &Str = CE->getOperand(0)->getStringValue(); + if (!Str.empty()) { unsigned len = Str.length(); const Type *Ty = cast<PointerType>(CE->getType())->getElementType(); unsigned numBits = Ty->getPrimitiveSizeInBits(); diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp index 6bc6ad4..79ec3d9 100644 --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -23,7 +23,6 @@ #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Support/IRBuilder.h" -#include "llvm/Analysis/ValueTracking.h" #include "llvm/Target/TargetData.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" @@ -230,6 +229,88 @@ void LibCallOptimization::EmitFWrite(Value *Ptr, Value *Size, Value *File, // Helper Functions //===----------------------------------------------------------------------===// +/// GetConstantStringInfo - This function computes the length of a +/// null-terminated C string pointed to by V. If successful, it returns true +/// and returns the string in Str. If unsuccessful, it returns false. +static bool GetConstantStringInfo(Value *V, std::string &Str) { + // Look bitcast instructions. + if (BitCastInst *BCI = dyn_cast<BitCastInst>(V)) + return GetConstantStringInfo(BCI->getOperand(0), Str); + + // If the value is not a GEP instruction nor a constant expression with a + // GEP instruction, then return false because ConstantArray can't occur + // any other way + 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 false; + GEP = CE; + } else { + return false; + } + + // Make sure the GEP has exactly three arguments. + if (GEP->getNumOperands() != 3) + return false; + + // 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 false; + } else + return false; + + // 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 false; + + // 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()) + return false; + Constant *GlobalInit = GV->getInitializer(); + + // Handle the ConstantAggregateZero case + if (isa<ConstantAggregateZero>(GlobalInit)) { + // This is a degenerate case. The initializer is constant zero so the + // length of the string must be zero. + Str.clear(); + return true; + } + + // Must be a Constant Array + ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit); + if (Array == 0 || Array->getType()->getElementType() != Type::Int8Ty) + 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 false; + if (CI->isZero()) + return true; // we found end of string, success! + Str += (char)CI->getZExtValue(); + } + + return false; // The array isn't null terminated. +} + /// 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) { diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 7a08b5f..b9976a7 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -2658,4 +2658,44 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, // Delete the old constant! destroyConstant(); -}
\ No newline at end of file +} + + +/// getStringValue - Turn an LLVM constant pointer that eventually points to a +/// global into a string value. Return an empty string if we can't do it. +/// Parameter Chop determines if the result is chopped at the first null +/// terminator. +/// +std::string Constant::getStringValue(bool Chop, unsigned Offset) { + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(this)) { + if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) { + ConstantArray *Init = cast<ConstantArray>(GV->getInitializer()); + if (Init->isString()) { + std::string Result = Init->getAsString(); + if (Offset < Result.size()) { + // If we are pointing INTO The string, erase the beginning... + Result.erase(Result.begin(), Result.begin()+Offset); + + // Take off the null terminator, and any string fragments after it. + if (Chop) { + std::string::size_type NullPos = Result.find_first_of((char)0); + if (NullPos != std::string::npos) + Result.erase(Result.begin()+NullPos, Result.end()); + } + return Result; + } + } + } + } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(this)) { + if (CE->getOpcode() == Instruction::GetElementPtr) { + // Turn a gep into the specified offset. + if (CE->getNumOperands() == 3 && + cast<Constant>(CE->getOperand(1))->isNullValue() && + isa<ConstantInt>(CE->getOperand(2))) { + Offset += cast<ConstantInt>(CE->getOperand(2))->getZExtValue(); + return CE->getOperand(0)->getStringValue(Chop, Offset); + } + } + } + return ""; +} diff --git a/lib/VMCore/IntrinsicInst.cpp b/lib/VMCore/IntrinsicInst.cpp index 6bd9431..eca6062 100644 --- a/lib/VMCore/IntrinsicInst.cpp +++ b/lib/VMCore/IntrinsicInst.cpp @@ -28,7 +28,6 @@ #include "llvm/IntrinsicInst.h" #include "llvm/Constants.h" #include "llvm/GlobalVariable.h" -#include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/MachineDebugInfoDesc.h" #include "llvm/CodeGen/MachineModuleInfo.h" using namespace llvm; @@ -59,20 +58,20 @@ Value *DbgInfoIntrinsic::StripCast(Value *C) { /// DbgStopPointInst - This represents the llvm.dbg.stoppoint instruction. /// -Value *DbgStopPointInst::getFileName() const { +std::string DbgStopPointInst::getFileName() const { // Once the operand indices are verified, update this assert assert(LLVMDebugVersion == (6 << 16) && "Verify operand indices"); GlobalVariable *GV = cast<GlobalVariable>(getContext()); - if (!GV->hasInitializer()) return NULL; + if (!GV->hasInitializer()) return ""; ConstantStruct *CS = cast<ConstantStruct>(GV->getInitializer()); - return CS->getOperand(4); + return CS->getOperand(3)->getStringValue(); } -Value *DbgStopPointInst::getDirectory() const { +std::string DbgStopPointInst::getDirectory() const { // Once the operand indices are verified, update this assert assert(LLVMDebugVersion == (6 << 16) && "Verify operand indices"); GlobalVariable *GV = cast<GlobalVariable>(getContext()); - if (!GV->hasInitializer()) return NULL; + if (!GV->hasInitializer()) return ""; ConstantStruct *CS = cast<ConstantStruct>(GV->getInitializer()); - return CS->getOperand(4); + return CS->getOperand(4)->getStringValue(); } |