llvm.org GIT mirror llvm / 71bf3e2
cleanups for strlen optimizer git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35711 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 12 years ago
1 changed file(s) with 21 addition(s) and 34 deletion(s). Raw diff Collapse all Expand all
798798
799799 /// @brief Make sure that the "strlen" function has the right prototype
800800 virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
801 if (F->getReturnType() == SLC.getTargetData()->getIntPtrType())
802 if (F->arg_size() == 1)
803 if (Function::const_arg_iterator AI = F->arg_begin())
804 if (AI->getType() == PointerType::get(Type::Int8Ty))
805 return true;
806 return false;
801 const FunctionType *FT = F->getFunctionType();
802 return FT->getNumParams() == 1 &&
803 FT->getParamType(0) == PointerType::get(Type::Int8Ty) &&
804 isa(FT->getReturnType());
807805 }
808806
809807 /// @brief Perform the strlen optimization
810 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
811 {
808 virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
812809 // Make sure we're dealing with an sbyte* here.
813 Value* str = ci->getOperand(1);
814 if (str->getType() != PointerType::get(Type::Int8Ty))
815 return false;
810 Value *Str = CI->getOperand(1);
816811
817812 // Does the call to strlen have exactly one use?
818 if (ci->hasOneUse())
813 if (CI->hasOneUse()) {
819814 // Is that single use a icmp operator?
820 if (ICmpInst* bop = dyn_cast(ci->use_back()))
815 if (ICmpInst *Cmp = dyn_cast(CI->use_back()))
821816 // Is it compared against a constant integer?
822 if (ConstantInt* CI = dyn_cast(bop->getOperand(1)))
823 {
824 // Get the value the strlen result is compared to
825 uint64_t val = CI->getZExtValue();
826
817 if (ConstantInt *Cst = dyn_cast(Cmp->getOperand(1))) {
827818 // If its compared against length 0 with == or !=
828 if (val == 0 &&
829 (bop->getPredicate() == ICmpInst::ICMP_EQ ||
830 bop->getPredicate() == ICmpInst::ICMP_NE))
831 {
819 if (Cst->getZExtValue() == 0 && Cmp->isEquality()) {
832820 // strlen(x) != 0 -> *x != 0
833821 // strlen(x) == 0 -> *x == 0
834 LoadInst* load = new LoadInst(str,str->getName()+".first",ci);
835 ICmpInst* rbop = new ICmpInst(bop->getPredicate(), load,
836 ConstantInt::get(Type::Int8Ty,0),
837 bop->getName()+".strlen", ci);
838 bop->replaceAllUsesWith(rbop);
839 bop->eraseFromParent();
840 ci->eraseFromParent();
841 return true;
822 Value *V = new LoadInst(Str, Str->getName()+".first", CI);
823 V = new ICmpInst(Cmp->getPredicate(), V,
824 ConstantInt::get(Type::Int8Ty, 0),
825 Cmp->getName()+".strlen", CI);
826 Cmp->replaceAllUsesWith(V);
827 Cmp->eraseFromParent();
828 return ReplaceCallWith(CI, 0); // no uses.
842829 }
843830 }
831 }
844832
845833 // Get the length of the constant string operand
846 uint64_t len = 0, StartIdx;
834 uint64_t StrLen = 0, StartIdx;
847835 ConstantArray *A;
848 if (!GetConstantStringInfo(ci->getOperand(1), A, len, StartIdx))
836 if (!GetConstantStringInfo(CI->getOperand(1), A, StrLen, StartIdx))
849837 return false;
850838
851839 // strlen("xyz") -> 3 (for example)
852 const Type *Ty = SLC.getTargetData()->getIntPtrType();
853 return ReplaceCallWith(ci, ConstantInt::get(Ty, len));
840 return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), StrLen));
854841 }
855842 } StrLenOptimizer;
856843