diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2005-05-04 18:58:28 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2005-05-04 18:58:28 +0000 |
commit | cea6559f602392b5be5d2c20e3bc5dc00d067e51 (patch) | |
tree | c85646dcda64e908009d94f3570578e64add8bce | |
parent | 3ec93c593c820b8626e4649fbbf41abb03a3a311 (diff) |
Implement the IsDigitOptimization for simplifying calls to the isdigit
library function:
isdigit(chr) -> 0 or 1 if chr is constant
isdigit(chr) -> chr - '0' <= 9 otherwise
Although there are many calls to isdigit in llvm-test, most of them are
compiled away by macros leaving only this:
2 MultiSource/Applications/hexxagon
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21688 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/IPO/SimplifyLibCalls.cpp | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/lib/Transforms/IPO/SimplifyLibCalls.cpp b/lib/Transforms/IPO/SimplifyLibCalls.cpp index 4c1fe29c2a..c92855c156 100644 --- a/lib/Transforms/IPO/SimplifyLibCalls.cpp +++ b/lib/Transforms/IPO/SimplifyLibCalls.cpp @@ -1554,6 +1554,60 @@ public: } } PutsOptimizer; +/// This LibCallOptimization will simplify calls to the "isdigit" library +/// function. It simply does range checks the parameter explicitly. +/// @brief Simplify the isdigit library function. +struct IsDigitOptimization : public LibCallOptimization +{ +public: + /// @brief Default Constructor + IsDigitOptimization() : LibCallOptimization("isdigit", + "simplify-libcalls:isdigit", "Number of 'isdigit' calls simplified") {} + + /// @brief Destructor + virtual ~IsDigitOptimization() {} + + /// @brief Make sure that the "fputs" function has the right prototype + virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) + { + // Just make sure this has 1 argument + return (f->arg_size() == 1); + } + + /// @brief Perform the toascii optimization. + virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC) + { + if (ConstantInt* CI = dyn_cast<ConstantInt>(ci->getOperand(1))) + { + // isdigit(c) -> 0 or 1, if 'c' is constant + uint64_t val = CI->getRawValue(); + if (val >= '0' && val <='9') + ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,1)); + else + ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,0)); + ci->eraseFromParent(); + return true; + } + + // isdigit(c) -> (unsigned)c - '0' <= 9 + CastInst* cast = + new CastInst(ci->getOperand(1),Type::UIntTy, + ci->getOperand(1)->getName()+".uint",ci); + BinaryOperator* sub_inst = BinaryOperator::create(Instruction::Sub,cast, + ConstantUInt::get(Type::UIntTy,0x30), + ci->getOperand(1)->getName()+".sub",ci); + SetCondInst* setcond_inst = new SetCondInst(Instruction::SetLE,sub_inst, + ConstantUInt::get(Type::UIntTy,9), + ci->getOperand(1)->getName()+".cmp",ci); + CastInst* c2 = + new CastInst(setcond_inst,Type::IntTy, + ci->getOperand(1)->getName()+".isdigit",ci); + ci->replaceAllUsesWith(c2); + ci->eraseFromParent(); + return true; + } +} IsDigitOptimizer; + /// This LibCallOptimization will simplify calls to the "toascii" library /// function. It simply does the corresponding and operation to restrict the /// range of values to the ASCII character set (0-127). @@ -1751,12 +1805,6 @@ bool getConstantStringLength(Value* V, uint64_t& len, ConstantArray** CA ) // * signbit(cnst) -> cnst' // * signbit(nncst) -> 0 (if pstv is a non-negative constant) // -// sprintf: -// * sprintf(dest,fmt) -> strcpy(dest,fmt) -// (if fmt is constant and constains no % characters) -// * sprintf(dest,"%s",orig) -> strcpy(dest,orig) -// (only if the sprintf result is not used) -// // sqrt, sqrtf, sqrtl: // * sqrt(expN(x)) -> expN(x*0.5) // * sqrt(Nroot(x)) -> pow(x,1/(2*N)) |