summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-09-10 21:15:22 +0000
committerChris Lattner <sabre@nondot.org>2007-09-10 21:15:22 +0000
commit87b51bc2b0e9bced27d6fd95573a3f21691a261c (patch)
tree95035c96425823dbd3ff8574f2611659fe8043a9 /lib
parent8d9455d4e4f63c368f17b74a36b472fc61685310 (diff)
downloadllvm-87b51bc2b0e9bced27d6fd95573a3f21691a261c.tar.gz
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')
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp90
1 files changed, 52 insertions, 38 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index e18beb5018ad..60b5290607a5 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;