mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-26 12:20:42 +00:00
instcombine: Migrate fprintf optimizations
This patch migrates the fprintf optimizations from the simplify-libcalls pass into the instcombine library call simplifier. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168891 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -81,19 +81,6 @@ public:
|
||||
} // End anonymous namespace.
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Helper Functions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static bool CallHasFloatingPointArgument(const CallInst *CI) {
|
||||
for (CallInst::const_op_iterator it = CI->op_begin(), e = CI->op_end();
|
||||
it != e; ++it) {
|
||||
if ((*it)->getType()->isFloatingPointTy())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Formatting and IO Optimizations
|
||||
@@ -160,84 +147,6 @@ struct FPutsOpt : public LibCallOptimization {
|
||||
}
|
||||
};
|
||||
|
||||
//===---------------------------------------===//
|
||||
// 'fprintf' Optimizations
|
||||
|
||||
struct FPrintFOpt : public LibCallOptimization {
|
||||
Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI,
|
||||
IRBuilder<> &B) {
|
||||
// All the optimizations depend on the format string.
|
||||
StringRef FormatStr;
|
||||
if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr))
|
||||
return 0;
|
||||
|
||||
// fprintf(F, "foo") --> fwrite("foo", 3, 1, F)
|
||||
if (CI->getNumArgOperands() == 2) {
|
||||
for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
|
||||
if (FormatStr[i] == '%') // Could handle %% -> % if we cared.
|
||||
return 0; // We found a format specifier.
|
||||
|
||||
// These optimizations require DataLayout.
|
||||
if (!TD) return 0;
|
||||
|
||||
Value *NewCI = EmitFWrite(CI->getArgOperand(1),
|
||||
ConstantInt::get(TD->getIntPtrType(*Context),
|
||||
FormatStr.size()),
|
||||
CI->getArgOperand(0), B, TD, TLI);
|
||||
return NewCI ? ConstantInt::get(CI->getType(), FormatStr.size()) : 0;
|
||||
}
|
||||
|
||||
// The remaining optimizations require the format string to be "%s" or "%c"
|
||||
// and have an extra operand.
|
||||
if (FormatStr.size() != 2 || FormatStr[0] != '%' ||
|
||||
CI->getNumArgOperands() < 3)
|
||||
return 0;
|
||||
|
||||
// Decode the second character of the format string.
|
||||
if (FormatStr[1] == 'c') {
|
||||
// fprintf(F, "%c", chr) --> fputc(chr, F)
|
||||
if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0;
|
||||
Value *NewCI = EmitFPutC(CI->getArgOperand(2), CI->getArgOperand(0), B,
|
||||
TD, TLI);
|
||||
return NewCI ? ConstantInt::get(CI->getType(), 1) : 0;
|
||||
}
|
||||
|
||||
if (FormatStr[1] == 's') {
|
||||
// fprintf(F, "%s", str) --> fputs(str, F)
|
||||
if (!CI->getArgOperand(2)->getType()->isPointerTy() || !CI->use_empty())
|
||||
return 0;
|
||||
return EmitFPutS(CI->getArgOperand(2), CI->getArgOperand(0), B, TD, TLI);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
|
||||
// Require two fixed paramters as pointers and integer result.
|
||||
FunctionType *FT = Callee->getFunctionType();
|
||||
if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
|
||||
!FT->getParamType(1)->isPointerTy() ||
|
||||
!FT->getReturnType()->isIntegerTy())
|
||||
return 0;
|
||||
|
||||
if (Value *V = OptimizeFixedFormatString(Callee, CI, B)) {
|
||||
return V;
|
||||
}
|
||||
|
||||
// fprintf(stream, format, ...) -> fiprintf(stream, format, ...) if no
|
||||
// floating point arguments.
|
||||
if (TLI->has(LibFunc::fiprintf) && !CallHasFloatingPointArgument(CI)) {
|
||||
Module *M = B.GetInsertBlock()->getParent()->getParent();
|
||||
Constant *FIPrintFFn =
|
||||
M->getOrInsertFunction("fiprintf", FT, Callee->getAttributes());
|
||||
CallInst *New = cast<CallInst>(CI->clone());
|
||||
New->setCalledFunction(FIPrintFFn);
|
||||
B.Insert(New);
|
||||
return New;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
//===---------------------------------------===//
|
||||
// 'puts' Optimizations
|
||||
|
||||
@@ -280,7 +189,7 @@ namespace {
|
||||
|
||||
StringMap<LibCallOptimization*> Optimizations;
|
||||
// Formatting and IO Optimizations
|
||||
FWriteOpt FWrite; FPutsOpt FPuts; FPrintFOpt FPrintF;
|
||||
FWriteOpt FWrite; FPutsOpt FPuts;
|
||||
PutsOpt Puts;
|
||||
|
||||
bool Modified; // This is only used by doInitialization.
|
||||
@@ -339,7 +248,6 @@ void SimplifyLibCalls::InitOptimizations() {
|
||||
// Formatting and IO Optimizations
|
||||
AddOpt(LibFunc::fwrite, &FWrite);
|
||||
AddOpt(LibFunc::fputs, &FPuts);
|
||||
Optimizations["fprintf"] = &FPrintF;
|
||||
Optimizations["puts"] = &Puts;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user