diff options
author | Eric Christopher <echristo@apple.com> | 2008-06-26 00:31:12 +0000 |
---|---|---|
committer | Eric Christopher <echristo@apple.com> | 2008-06-26 00:31:12 +0000 |
commit | 0d2b0aba424bd3959bb5c807873def8f53e57a3c (patch) | |
tree | c8c5920b98cb731179014d6db62b95062800d8c4 /lib | |
parent | cda8875433ef74c39c4151d1a58df0588168b2e2 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52748 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/ValueTracking.cpp | 86 | ||||
-rw-r--r-- | lib/CodeGen/MachineModuleInfo.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 4 | ||||
-rw-r--r-- | lib/Debugger/ProgramInfo.cpp | 10 | ||||
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 4 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 42 | ||||
-rw-r--r-- | lib/VMCore/IntrinsicInst.cpp | 13 |
7 files changed, 111 insertions, 55 deletions
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 32a77e6f46..3c4e6bc696 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -15,6 +15,7 @@ #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" @@ -930,3 +931,88 @@ 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) { + // 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); + + // 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. +} diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index 2bad6bba83..1720745e44 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -10,6 +10,7 @@ #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" @@ -230,7 +231,11 @@ public: } virtual void Apply(std::string &Field) { Constant *C = CI->getOperand(I++); - Field = C->getStringValue(); + std::string S; + if (GetConstantStringInfo(C, S)) + Field = S; + else + Field = ""; } 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 f1c2ecf19d..9c5997df45 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #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" @@ -2594,8 +2595,7 @@ static bool isMemSrcFromString(SDOperand Src, std::string &Str, GlobalVariable *GV = dyn_cast<GlobalVariable>(G->getGlobal()); if (GV && GV->isConstant()) { - Str = GV->getStringValue(false); - if (!Str.empty()) { + if (GetConstantStringInfo(GV, Str)) { SrcOff += SrcDelta; return true; } diff --git a/lib/Debugger/ProgramInfo.cpp b/lib/Debugger/ProgramInfo.cpp index e4380ea427..408704dad1 100644 --- a/lib/Debugger/ProgramInfo.cpp +++ b/lib/Debugger/ProgramInfo.cpp @@ -14,6 +14,7 @@ #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" @@ -115,8 +116,10 @@ SourceFileInfo::SourceFileInfo(const GlobalVariable *Desc, if (ConstantInt *CUI = dyn_cast<ConstantInt>(CS->getOperand(1))) Version = CUI->getZExtValue(); - BaseName = CS->getOperand(3)->getStringValue(); - Directory = CS->getOperand(4)->getStringValue(); + if (!GetConstantStringInfo(CS->getOperand(3), BaseName)) + BaseName = ""; + if (!GetConstantStringInfo(CS->getOperand(4), Directory)) + Directory = ""; } } @@ -156,7 +159,8 @@ SourceFunctionInfo::SourceFunctionInfo(ProgramInfo &PI, SourceFile = &PI.getSourceFile(GV); // Entry #2 is the function name. - Name = CS->getOperand(2)->getStringValue(); + if (!GetConstantStringInfo(CS->getOperand(2), Name)) + Name = ""; } } diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index d45eb99d93..5d75489d14 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. - const std::string &Str = CE->getOperand(0)->getStringValue(); - if (!Str.empty()) { + std::string Str; + if (GetConstantStringInfo(CE->getOperand(0), Str) && !Str.empty()) { unsigned len = Str.length(); const Type *Ty = cast<PointerType>(CE->getType())->getElementType(); unsigned numBits = Ty->getPrimitiveSizeInBits(); diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index b9976a7207..7a08b5fb8f 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -2658,44 +2658,4 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, // Delete the old constant! destroyConstant(); -} - - -/// 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 ""; -} +}
\ No newline at end of file diff --git a/lib/VMCore/IntrinsicInst.cpp b/lib/VMCore/IntrinsicInst.cpp index 94f582911e..312a47f2c7 100644 --- a/lib/VMCore/IntrinsicInst.cpp +++ b/lib/VMCore/IntrinsicInst.cpp @@ -28,6 +28,7 @@ #include "llvm/IntrinsicInst.h" #include "llvm/Constants.h" #include "llvm/GlobalVariable.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/MachineModuleInfo.h" using namespace llvm; @@ -57,20 +58,20 @@ Value *DbgInfoIntrinsic::StripCast(Value *C) { /// DbgStopPointInst - This represents the llvm.dbg.stoppoint instruction. /// -std::string DbgStopPointInst::getFileName() const { +Value *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 ""; + if (!GV->hasInitializer()) return NULL; ConstantStruct *CS = cast<ConstantStruct>(GV->getInitializer()); - return CS->getOperand(3)->getStringValue(); + return CS->getOperand(4); } -std::string DbgStopPointInst::getDirectory() const { +Value *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 ""; + if (!GV->hasInitializer()) return NULL; ConstantStruct *CS = cast<ConstantStruct>(GV->getInitializer()); - return CS->getOperand(4)->getStringValue(); + return CS->getOperand(4); } |