1. Don't call Value::getName(), which is slow.

2. Lower calls to fabs and friends to FABS nodes etc unless the function has
   internal linkage.  Before we wouldn't lower if it had a definition, which
   is incorrect.  This allows us to compile:

define double @fabs(double %f) {
        %tmp2 = tail call double @fabs( double %f )
        ret double %tmp2
}

into:

_fabs:
        fabs f1, f1
        blr 



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41805 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-09-10 21:15:22 +00:00
parent 8d9455d4e4
commit 87b51bc2b0

View File

@ -2969,50 +2969,64 @@ void SelectionDAGLowering::LowerCallTo(Instruction &I,
void SelectionDAGLowering::visitCall(CallInst &I) { void SelectionDAGLowering::visitCall(CallInst &I) {
const char *RenameFn = 0; const char *RenameFn = 0;
if (Function *F = I.getCalledFunction()) { if (Function *F = I.getCalledFunction()) {
if (F->isDeclaration()) if (F->isDeclaration()) {
if (unsigned IID = F->getIntrinsicID()) { if (unsigned IID = F->getIntrinsicID()) {
RenameFn = visitIntrinsicCall(I, IID); RenameFn = visitIntrinsicCall(I, IID);
if (!RenameFn) if (!RenameFn)
return; return;
} else { // Not an LLVM intrinsic. }
const std::string &Name = F->getName(); }
if (Name[0] == 'c' && (Name == "copysign" || Name == "copysignf")) {
if (I.getNumOperands() == 3 && // Basic sanity checks. // Check for well-known libc/libm calls. If the function is internal, it
I.getOperand(1)->getType()->isFloatingPoint() && // can't be a library call.
I.getType() == I.getOperand(1)->getType() && unsigned NameLen = F->getNameLen();
I.getType() == I.getOperand(2)->getType()) { if (!F->hasInternalLinkage() && NameLen) {
SDOperand LHS = getValue(I.getOperand(1)); const char *NameStr = F->getNameStart();
SDOperand RHS = getValue(I.getOperand(2)); if (NameStr[0] == 'c' &&
setValue(&I, DAG.getNode(ISD::FCOPYSIGN, LHS.getValueType(), ((NameLen == 8 && !strcmp(NameStr, "copysign")) ||
LHS, RHS)); (NameLen == 9 && !strcmp(NameStr, "copysignf")))) {
return; if (I.getNumOperands() == 3 && // Basic sanity checks.
} I.getOperand(1)->getType()->isFloatingPoint() &&
} else if (Name[0] == 'f' && (Name == "fabs" || Name == "fabsf")) { I.getType() == I.getOperand(1)->getType() &&
if (I.getNumOperands() == 2 && // Basic sanity checks. I.getType() == I.getOperand(2)->getType()) {
I.getOperand(1)->getType()->isFloatingPoint() && SDOperand LHS = getValue(I.getOperand(1));
I.getType() == I.getOperand(1)->getType()) { SDOperand RHS = getValue(I.getOperand(2));
SDOperand Tmp = getValue(I.getOperand(1)); setValue(&I, DAG.getNode(ISD::FCOPYSIGN, LHS.getValueType(),
setValue(&I, DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp)); LHS, RHS));
return; return;
} }
} else if (Name[0] == 's' && (Name == "sin" || Name == "sinf")) { } else if (NameStr[0] == 'f' &&
if (I.getNumOperands() == 2 && // Basic sanity checks. ((NameLen == 4 && !strcmp(NameStr, "fabs")) ||
I.getOperand(1)->getType()->isFloatingPoint() && (NameLen == 5 && !strcmp(NameStr, "fabsf")))) {
I.getType() == I.getOperand(1)->getType()) { if (I.getNumOperands() == 2 && // Basic sanity checks.
SDOperand Tmp = getValue(I.getOperand(1)); I.getOperand(1)->getType()->isFloatingPoint() &&
setValue(&I, DAG.getNode(ISD::FSIN, Tmp.getValueType(), Tmp)); I.getType() == I.getOperand(1)->getType()) {
return; SDOperand Tmp = getValue(I.getOperand(1));
} setValue(&I, DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp));
} else if (Name[0] == 'c' && (Name == "cos" || Name == "cosf")) { return;
if (I.getNumOperands() == 2 && // Basic sanity checks. }
I.getOperand(1)->getType()->isFloatingPoint() && } else if (NameStr[0] == 's' &&
I.getType() == I.getOperand(1)->getType()) { ((NameLen == 3 && !strcmp(NameStr, "sin")) ||
SDOperand Tmp = getValue(I.getOperand(1)); (NameLen == 4 && !strcmp(NameStr, "sinf")))) {
setValue(&I, DAG.getNode(ISD::FCOS, Tmp.getValueType(), Tmp)); if (I.getNumOperands() == 2 && // Basic sanity checks.
return; I.getOperand(1)->getType()->isFloatingPoint() &&
} I.getType() == I.getOperand(1)->getType()) {
SDOperand Tmp = getValue(I.getOperand(1));
setValue(&I, DAG.getNode(ISD::FSIN, Tmp.getValueType(), Tmp));
return;
}
} else if (NameStr[0] == 'c' &&
((NameLen == 3 && !strcmp(NameStr, "cos")) ||
(NameLen == 4 && !strcmp(NameStr, "cosf")))) {
if (I.getNumOperands() == 2 && // Basic sanity checks.
I.getOperand(1)->getType()->isFloatingPoint() &&
I.getType() == I.getOperand(1)->getType()) {
SDOperand Tmp = getValue(I.getOperand(1));
setValue(&I, DAG.getNode(ISD::FCOS, Tmp.getValueType(), Tmp));
return;
} }
} }
}
} else if (isa<InlineAsm>(I.getOperand(0))) { } else if (isa<InlineAsm>(I.getOperand(0))) {
visitInlineAsm(I); visitInlineAsm(I);
return; return;