[llvm-commits] CVS: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp
Chris Lattner
sabre at nondot.org
Fri Apr 13 18:18:10 PDT 2007
Changes in directory llvm/lib/Transforms/IPO:
SimplifyLibCalls.cpp updated: 1.110 -> 1.111
---
Log message:
Implement a few missing xforms: printf("foo\n") -> puts. printf("x") -> putchar
printf("") -> noop. Still need to do the xforms for fprintf.
This implements Transforms/SimplifyLibCalls/Printf.ll
---
Diffs of the changes: (+48 -9)
SimplifyLibCalls.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 48 insertions(+), 9 deletions(-)
Index: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp
diff -u llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.110 llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.111
--- llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.110 Sun Apr 8 13:11:26 2007
+++ llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Fri Apr 13 20:17:48 2007
@@ -1154,22 +1154,61 @@
/// @brief Make sure that the "printf" function has the right prototype
virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
- // Just make sure this has at least 1 arguments
- return F->arg_size() >= 1;
+ // Just make sure this has at least 1 argument and returns an integer or
+ // void type.
+ const FunctionType *FT = F->getFunctionType();
+ return FT->getNumParams() >= 1 &&
+ (isa<IntegerType>(FT->getReturnType()) ||
+ FT->getReturnType() == Type::VoidTy);
}
/// @brief Perform the printf optimization.
virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
- // If the call has more than 2 operands, we can't optimize it
- if (CI->getNumOperands() != 3)
- return false;
-
// All the optimizations depend on the length of the first argument and the
// fact that it is a constant string array. Check that now
std::string FormatStr;
if (!GetConstantStringInfo(CI->getOperand(1), FormatStr))
return false;
+
+ // If this is a simple constant string with no format specifiers that ends
+ // with a \n, turn it into a puts call.
+ if (FormatStr.empty()) {
+ // Tolerate printf's declared void.
+ if (CI->use_empty()) return ReplaceCallWith(CI, 0);
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 0));
+ }
+
+ if (FormatStr.size() == 1) {
+ // Turn this into a putchar call, even if it is a %.
+ Value *V = ConstantInt::get(Type::Int32Ty, FormatStr[0]);
+ new CallInst(SLC.get_putchar(), V, "", CI);
+ if (CI->use_empty()) return ReplaceCallWith(CI, 0);
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 1));
+ }
+ // Check to see if the format str is something like "foo\n", in which case
+ // we convert it to a puts call. We don't allow it to contain any format
+ // characters.
+ if (FormatStr[FormatStr.size()-1] == '\n' &&
+ FormatStr.find('%') == std::string::npos) {
+ // Create a string literal with no \n on it. We expect the constant merge
+ // pass to be run after this pass, to merge duplicate strings.
+ FormatStr.erase(FormatStr.end()-1);
+ Constant *Init = ConstantArray::get(FormatStr, true);
+ Constant *GV = new GlobalVariable(Init->getType(), true,
+ GlobalVariable::InternalLinkage,
+ Init, "str",
+ CI->getParent()->getParent()->getParent());
+ // Cast GV to be a pointer to char.
+ GV = ConstantExpr::getBitCast(GV, PointerType::get(Type::Int8Ty));
+ new CallInst(SLC.get_puts(), GV, "", CI);
+
+ if (CI->use_empty()) return ReplaceCallWith(CI, 0);
+ return ReplaceCallWith(CI,
+ ConstantInt::get(CI->getType(), FormatStr.size()));
+ }
+
+
// Only support %c or "%s\n" for now.
if (FormatStr.size() < 2 || FormatStr[0] != '%')
return false;
@@ -1178,7 +1217,7 @@
switch (FormatStr[1]) {
default: return false;
case 's':
- if (FormatStr != "%s\n" ||
+ if (FormatStr != "%s\n" || CI->getNumOperands() < 3 ||
// TODO: could insert strlen call to compute string length.
!CI->use_empty())
return false;
@@ -1189,7 +1228,7 @@
return ReplaceCallWith(CI, 0);
case 'c': {
// printf("%c",c) -> putchar(c)
- if (FormatStr.size() != 2)
+ if (FormatStr.size() != 2 || CI->getNumOperands() < 3)
return false;
Value *V = CI->getOperand(2);
@@ -1917,7 +1956,7 @@
// * pow(pow(x,y),z)-> pow(x,y*z)
//
// puts:
-// * puts("") -> fputc("\n",stdout) (how do we get "stdout"?)
+// * puts("") -> putchar("\n")
//
// round, roundf, roundl:
// * round(cnst) -> cnst'
More information about the llvm-commits
mailing list