[llvm-commits] CVS: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp
Reid Spencer
reid at x10sys.com
Sat May 7 13:16:33 PDT 2005
Changes in directory llvm/lib/Transforms/IPO:
SimplifyLibCalls.cpp updated: 1.32 -> 1.33
---
Log message:
* Add two strlen optimizations:
strlen(x) != 0 -> *x != 0
strlen(x) == 0 -> *x == 0
* Change nested statistics to use style of other LLVM statistics so that
only the name of the optimization (simplify-libcalls) is used as the
statistic name, and the description indicates which specific all is
optimized. Cuts down on some redundancy and saves a few bytes of space.
* Make note of stpcpy optimization that could be done.
---
Diffs of the changes: (+56 -23)
SimplifyLibCalls.cpp | 79 ++++++++++++++++++++++++++++++++++++---------------
1 files changed, 56 insertions(+), 23 deletions(-)
Index: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp
diff -u llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.32 llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.33
--- llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.32 Fri May 6 23:59:45 2005
+++ llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Sat May 7 15:15:59 2005
@@ -35,7 +35,7 @@
/// This statistic keeps track of the total number of library calls that have
/// been simplified regardless of which call it is.
Statistic<> SimplifiedLibCalls("simplify-libcalls",
- "Number of well-known library calls simplified");
+ "Total number of library calls simplified");
// Forward declarations
class LibCallOptimization;
@@ -65,11 +65,10 @@
/// The \p fname argument must be the name of the library function being
/// optimized by the subclass.
/// @brief Constructor that registers the optimization.
- LibCallOptimization(const char* fname,
- const char* stat_name, const char* description )
+ LibCallOptimization(const char* fname, const char* description )
: func_name(fname)
#ifndef NDEBUG
- , occurrences(stat_name,description)
+ , occurrences("simplify-libcalls",description)
#endif
{
// Register this call optimizer in the optlist (a hash_map)
@@ -374,7 +373,7 @@
struct ExitInMainOptimization : public LibCallOptimization
{
ExitInMainOptimization() : LibCallOptimization("exit",
- "simplify-libcalls:exit","Number of 'exit' calls simplified") {}
+ "Number of 'exit' calls simplified") {}
virtual ~ExitInMainOptimization() {}
// Make sure the called function looks like exit (int argument, int return
@@ -440,7 +439,7 @@
public:
/// @brief Default constructor
StrCatOptimization() : LibCallOptimization("strcat",
- "simplify-libcalls:strcat","Number of 'strcat' calls simplified") {}
+ "Number of 'strcat' calls simplified") {}
public:
/// @breif Destructor
@@ -531,7 +530,7 @@
{
public:
StrChrOptimization() : LibCallOptimization("strchr",
- "simplify-libcalls:strchr","Number of 'strchr' calls simplified") {}
+ "Number of 'strchr' calls simplified") {}
virtual ~StrChrOptimization() {}
/// @brief Make sure that the "strchr" function has the right prototype
@@ -623,7 +622,7 @@
{
public:
StrCmpOptimization() : LibCallOptimization("strcmp",
- "simplify-libcalls:strcmp","Number of 'strcmp' calls simplified") {}
+ "Number of 'strcmp' calls simplified") {}
virtual ~StrCmpOptimization() {}
/// @brief Make sure that the "strcpy" function has the right prototype
@@ -708,7 +707,7 @@
{
public:
StrNCmpOptimization() : LibCallOptimization("strncmp",
- "simplify-libcalls:strncmp","Number of 'strncmp' calls simplified") {}
+ "Number of 'strncmp' calls simplified") {}
virtual ~StrNCmpOptimization() {}
/// @brief Make sure that the "strcpy" function has the right prototype
@@ -811,7 +810,7 @@
{
public:
StrCpyOptimization() : LibCallOptimization("strcpy",
- "simplify-libcalls:strcpy","Number of 'strcpy' calls simplified") {}
+ "Number of 'strcpy' calls simplified") {}
virtual ~StrCpyOptimization() {}
/// @brief Make sure that the "strcpy" function has the right prototype
@@ -899,7 +898,7 @@
struct StrLenOptimization : public LibCallOptimization
{
StrLenOptimization() : LibCallOptimization("strlen",
- "simplify-libcalls:strlen","Number of 'strlen' calls simplified") {}
+ "Number of 'strlen' calls simplified") {}
virtual ~StrLenOptimization() {}
/// @brief Make sure that the "strlen" function has the right prototype
@@ -916,11 +915,45 @@
/// @brief Perform the strlen optimization
virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
{
- // Get the length of the string
+ // Make sure we're dealing with an sbyte* here.
+ Value* str = ci->getOperand(1);
+ if (str->getType() != PointerType::get(Type::SByteTy))
+ return false;
+
+ // Does the call to strlen have exactly one use?
+ if (ci->hasOneUse())
+ // Is that single use a binary operator?
+ if (BinaryOperator* bop = dyn_cast<BinaryOperator>(ci->use_back()))
+ // Is it compared against a constant integer?
+ if (ConstantInt* CI = dyn_cast<ConstantInt>(bop->getOperand(1)))
+ {
+ // Get the value the strlen result is compared to
+ uint64_t val = CI->getRawValue();
+
+ // If its compared against length 0 with == or !=
+ if (val == 0 &&
+ (bop->getOpcode() == Instruction::SetEQ ||
+ bop->getOpcode() == Instruction::SetNE))
+ {
+ // strlen(x) != 0 -> *x != 0
+ // strlen(x) == 0 -> *x == 0
+ LoadInst* load = new LoadInst(str,str->getName()+".first",ci);
+ BinaryOperator* rbop = BinaryOperator::create(bop->getOpcode(),
+ load, ConstantSInt::get(Type::SByteTy,0),
+ bop->getName()+".strlen", ci);
+ bop->replaceAllUsesWith(rbop);
+ bop->eraseFromParent();
+ ci->eraseFromParent();
+ return true;
+ }
+ }
+
+ // Get the length of the constant string operand
uint64_t len = 0;
if (!getConstantStringLength(ci->getOperand(1),len))
return false;
+ // strlen("xyz") -> 3 (for example)
ci->replaceAllUsesWith(
ConstantInt::get(SLC.getTargetData()->getIntPtrType(),len));
ci->eraseFromParent();
@@ -937,13 +970,12 @@
{
/// @brief Default Constructor
LLVMMemCpyOptimization() : LibCallOptimization("llvm.memcpy",
- "simplify-libcalls:llvm.memcpy",
"Number of 'llvm.memcpy' calls simplified") {}
protected:
/// @brief Subclass Constructor
- LLVMMemCpyOptimization(const char* fname, const char* sname, const char* desc)
- : LibCallOptimization(fname, sname, desc) {}
+ LLVMMemCpyOptimization(const char* fname, const char* desc)
+ : LibCallOptimization(fname, desc) {}
public:
/// @brief Destructor
virtual ~LLVMMemCpyOptimization() {}
@@ -1017,7 +1049,6 @@
{
/// @brief Default Constructor
LLVMMemMoveOptimization() : LLVMMemCpyOptimization("llvm.memmove",
- "simplify-libcalls:llvm.memmove",
"Number of 'llvm.memmove' calls simplified") {}
} LLVMMemMoveOptimizer;
@@ -1029,7 +1060,6 @@
{
/// @brief Default Constructor
LLVMMemSetOptimization() : LibCallOptimization("llvm.memset",
- "simplify-libcalls:llvm.memset",
"Number of 'llvm.memset' calls simplified") {}
public:
@@ -1139,7 +1169,7 @@
public:
/// @brief Default Constructor
PowOptimization() : LibCallOptimization("pow",
- "simplify-libcalls:pow", "Number of 'pow' calls simplified") {}
+ "Number of 'pow' calls simplified") {}
/// @brief Destructor
virtual ~PowOptimization() {}
@@ -1216,7 +1246,7 @@
public:
/// @brief Default Constructor
FPrintFOptimization() : LibCallOptimization("fprintf",
- "simplify-libcalls:fprintf", "Number of 'fprintf' calls simplified") {}
+ "Number of 'fprintf' calls simplified") {}
/// @brief Destructor
virtual ~FPrintFOptimization() {}
@@ -1346,7 +1376,7 @@
public:
/// @brief Default Constructor
SPrintFOptimization() : LibCallOptimization("sprintf",
- "simplify-libcalls:sprintf", "Number of 'sprintf' calls simplified") {}
+ "Number of 'sprintf' calls simplified") {}
/// @brief Destructor
virtual ~SPrintFOptimization() {}
@@ -1489,7 +1519,7 @@
public:
/// @brief Default Constructor
PutsOptimization() : LibCallOptimization("fputs",
- "simplify-libcalls:fputs", "Number of 'fputs' calls simplified") {}
+ "Number of 'fputs' calls simplified") {}
/// @brief Destructor
virtual ~PutsOptimization() {}
@@ -1562,7 +1592,7 @@
public:
/// @brief Default Constructor
IsDigitOptimization() : LibCallOptimization("isdigit",
- "simplify-libcalls:isdigit", "Number of 'isdigit' calls simplified") {}
+ "Number of 'isdigit' calls simplified") {}
/// @brief Destructor
virtual ~IsDigitOptimization() {}
@@ -1617,7 +1647,7 @@
public:
/// @brief Default Constructor
ToAsciiOptimization() : LibCallOptimization("toascii",
- "simplify-libcalls:toascii", "Number of 'toascii' calls simplified") {}
+ "Number of 'toascii' calls simplified") {}
/// @brief Destructor
virtual ~ToAsciiOptimization() {}
@@ -1810,6 +1840,9 @@
// * sqrt(Nroot(x)) -> pow(x,1/(2*N))
// * sqrt(pow(x,y)) -> pow(|x|,y*0.5)
//
+// stpcpy:
+// * stpcpy(str, "literal") ->
+// llvm.memcpy(str,"literal",strlen("literal")+1,1)
// strrchr:
// * strrchr(s,c) -> reverse_offset_of_in(c,s)
// (if c is a constant integer and s is a constant string)
More information about the llvm-commits
mailing list