mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-24 08:33:39 +00:00
cleanups for strlen optimizer
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35711 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
679d7188c7
commit
71bf3e2ef9
@ -799,59 +799,46 @@ struct VISIBILITY_HIDDEN StrLenOptimization : public LibCallOptimization {
|
|||||||
|
|
||||||
/// @brief Make sure that the "strlen" function has the right prototype
|
/// @brief Make sure that the "strlen" function has the right prototype
|
||||||
virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
|
virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
|
||||||
if (F->getReturnType() == SLC.getTargetData()->getIntPtrType())
|
const FunctionType *FT = F->getFunctionType();
|
||||||
if (F->arg_size() == 1)
|
return FT->getNumParams() == 1 &&
|
||||||
if (Function::const_arg_iterator AI = F->arg_begin())
|
FT->getParamType(0) == PointerType::get(Type::Int8Ty) &&
|
||||||
if (AI->getType() == PointerType::get(Type::Int8Ty))
|
isa<IntegerType>(FT->getReturnType());
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Perform the strlen optimization
|
/// @brief Perform the strlen optimization
|
||||||
virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
|
virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
|
||||||
{
|
|
||||||
// Make sure we're dealing with an sbyte* here.
|
// Make sure we're dealing with an sbyte* here.
|
||||||
Value* str = ci->getOperand(1);
|
Value *Str = CI->getOperand(1);
|
||||||
if (str->getType() != PointerType::get(Type::Int8Ty))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Does the call to strlen have exactly one use?
|
// Does the call to strlen have exactly one use?
|
||||||
if (ci->hasOneUse())
|
if (CI->hasOneUse()) {
|
||||||
// Is that single use a icmp operator?
|
// Is that single use a icmp operator?
|
||||||
if (ICmpInst* bop = dyn_cast<ICmpInst>(ci->use_back()))
|
if (ICmpInst *Cmp = dyn_cast<ICmpInst>(CI->use_back()))
|
||||||
// Is it compared against a constant integer?
|
// Is it compared against a constant integer?
|
||||||
if (ConstantInt* CI = dyn_cast<ConstantInt>(bop->getOperand(1)))
|
if (ConstantInt *Cst = dyn_cast<ConstantInt>(Cmp->getOperand(1))) {
|
||||||
{
|
|
||||||
// Get the value the strlen result is compared to
|
|
||||||
uint64_t val = CI->getZExtValue();
|
|
||||||
|
|
||||||
// If its compared against length 0 with == or !=
|
// If its compared against length 0 with == or !=
|
||||||
if (val == 0 &&
|
if (Cst->getZExtValue() == 0 && Cmp->isEquality()) {
|
||||||
(bop->getPredicate() == ICmpInst::ICMP_EQ ||
|
|
||||||
bop->getPredicate() == ICmpInst::ICMP_NE))
|
|
||||||
{
|
|
||||||
// strlen(x) != 0 -> *x != 0
|
// strlen(x) != 0 -> *x != 0
|
||||||
// strlen(x) == 0 -> *x == 0
|
// strlen(x) == 0 -> *x == 0
|
||||||
LoadInst* load = new LoadInst(str,str->getName()+".first",ci);
|
Value *V = new LoadInst(Str, Str->getName()+".first", CI);
|
||||||
ICmpInst* rbop = new ICmpInst(bop->getPredicate(), load,
|
V = new ICmpInst(Cmp->getPredicate(), V,
|
||||||
ConstantInt::get(Type::Int8Ty,0),
|
ConstantInt::get(Type::Int8Ty, 0),
|
||||||
bop->getName()+".strlen", ci);
|
Cmp->getName()+".strlen", CI);
|
||||||
bop->replaceAllUsesWith(rbop);
|
Cmp->replaceAllUsesWith(V);
|
||||||
bop->eraseFromParent();
|
Cmp->eraseFromParent();
|
||||||
ci->eraseFromParent();
|
return ReplaceCallWith(CI, 0); // no uses.
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get the length of the constant string operand
|
// Get the length of the constant string operand
|
||||||
uint64_t len = 0, StartIdx;
|
uint64_t StrLen = 0, StartIdx;
|
||||||
ConstantArray *A;
|
ConstantArray *A;
|
||||||
if (!GetConstantStringInfo(ci->getOperand(1), A, len, StartIdx))
|
if (!GetConstantStringInfo(CI->getOperand(1), A, StrLen, StartIdx))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// strlen("xyz") -> 3 (for example)
|
// strlen("xyz") -> 3 (for example)
|
||||||
const Type *Ty = SLC.getTargetData()->getIntPtrType();
|
return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), StrLen));
|
||||||
return ReplaceCallWith(ci, ConstantInt::get(Ty, len));
|
|
||||||
}
|
}
|
||||||
} StrLenOptimizer;
|
} StrLenOptimizer;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user