diff options
author | Chris Lattner <sabre@nondot.org> | 2007-09-10 21:15:22 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-09-10 21:15:22 +0000 |
commit | 3687e34c2cc7ce435bc29e9cacdb4d7320890b91 (patch) | |
tree | 95035c96425823dbd3ff8574f2611659fe8043a9 /lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | |
parent | 308ae14239c1cbeb73da0726311ef558498cfab0 (diff) | |
download | external_llvm-3687e34c2cc7ce435bc29e9cacdb4d7320890b91.zip external_llvm-3687e34c2cc7ce435bc29e9cacdb4d7320890b91.tar.gz external_llvm-3687e34c2cc7ce435bc29e9cacdb4d7320890b91.tar.bz2 |
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
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 90 |
1 files changed, 52 insertions, 38 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index e18beb5..60b5290 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2969,50 +2969,64 @@ void SelectionDAGLowering::LowerCallTo(Instruction &I, void SelectionDAGLowering::visitCall(CallInst &I) { const char *RenameFn = 0; if (Function *F = I.getCalledFunction()) { - if (F->isDeclaration()) + if (F->isDeclaration()) { if (unsigned IID = F->getIntrinsicID()) { RenameFn = visitIntrinsicCall(I, IID); if (!RenameFn) 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. - I.getOperand(1)->getType()->isFloatingPoint() && - I.getType() == I.getOperand(1)->getType() && - I.getType() == I.getOperand(2)->getType()) { - SDOperand LHS = getValue(I.getOperand(1)); - SDOperand RHS = getValue(I.getOperand(2)); - setValue(&I, DAG.getNode(ISD::FCOPYSIGN, LHS.getValueType(), - LHS, RHS)); - return; - } - } else if (Name[0] == 'f' && (Name == "fabs" || Name == "fabsf")) { - 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::FABS, Tmp.getValueType(), Tmp)); - return; - } - } else if (Name[0] == 's' && (Name == "sin" || Name == "sinf")) { - 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::FSIN, Tmp.getValueType(), Tmp)); - return; - } - } else if (Name[0] == 'c' && (Name == "cos" || Name == "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; - } + } + } + + // Check for well-known libc/libm calls. If the function is internal, it + // can't be a library call. + unsigned NameLen = F->getNameLen(); + if (!F->hasInternalLinkage() && NameLen) { + const char *NameStr = F->getNameStart(); + if (NameStr[0] == 'c' && + ((NameLen == 8 && !strcmp(NameStr, "copysign")) || + (NameLen == 9 && !strcmp(NameStr, "copysignf")))) { + if (I.getNumOperands() == 3 && // Basic sanity checks. + I.getOperand(1)->getType()->isFloatingPoint() && + I.getType() == I.getOperand(1)->getType() && + I.getType() == I.getOperand(2)->getType()) { + SDOperand LHS = getValue(I.getOperand(1)); + SDOperand RHS = getValue(I.getOperand(2)); + setValue(&I, DAG.getNode(ISD::FCOPYSIGN, LHS.getValueType(), + LHS, RHS)); + return; + } + } else if (NameStr[0] == 'f' && + ((NameLen == 4 && !strcmp(NameStr, "fabs")) || + (NameLen == 5 && !strcmp(NameStr, "fabsf")))) { + 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::FABS, Tmp.getValueType(), Tmp)); + return; + } + } else if (NameStr[0] == 's' && + ((NameLen == 3 && !strcmp(NameStr, "sin")) || + (NameLen == 4 && !strcmp(NameStr, "sinf")))) { + 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::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))) { visitInlineAsm(I); return; |