Enhance both TargetLibraryInfo and SelectionDAGBuilder so that the latter can use the former to prevent the formation of libm SDNode's when -fno-builtin is passed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146193 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Owen Anderson
2011-12-08 22:15:21 +00:00
parent 6b044c2609
commit 243eb9ecbb
6 changed files with 82 additions and 16 deletions

View File

@ -29,6 +29,7 @@ namespace llvm {
class MachineFunction; class MachineFunction;
class MachineInstr; class MachineInstr;
class TargetLowering; class TargetLowering;
class TargetLibraryInfo;
class TargetInstrInfo; class TargetInstrInfo;
class FunctionLoweringInfo; class FunctionLoweringInfo;
class ScheduleHazardRecognizer; class ScheduleHazardRecognizer;
@ -42,6 +43,7 @@ class SelectionDAGISel : public MachineFunctionPass {
public: public:
const TargetMachine &TM; const TargetMachine &TM;
const TargetLowering &TLI; const TargetLowering &TLI;
const TargetLibraryInfo *LibInfo;
FunctionLoweringInfo *FuncInfo; FunctionLoweringInfo *FuncInfo;
MachineFunction *MF; MachineFunction *MF;
MachineRegisterInfo *RegInfo; MachineRegisterInfo *RegInfo;

View File

@ -48,6 +48,12 @@ namespace llvm {
ceill, ceill,
/// float ceilf(float x); /// float ceilf(float x);
ceilf, ceilf,
/// double copysign(double x, double y);
copysign,
/// float copysignf(float x, float y);
copysignf,
/// long double copysignl(long double x, long double y);
copysignl,
/// double cos(double x); /// double cos(double x);
cos, cos,
/// long double cosl(long double x); /// long double cosl(long double x);
@ -137,12 +143,24 @@ namespace llvm {
memset, memset,
/// void memset_pattern16(void *b, const void *pattern16, size_t len); /// void memset_pattern16(void *b, const void *pattern16, size_t len);
memset_pattern16, memset_pattern16,
/// double nearbyint(double x);
nearbyint,
/// float nearbyintf(float x);
nearbyintf,
/// long double nearbyintl(long double x);
nearbyintl,
/// double pow(double x, double y); /// double pow(double x, double y);
pow, pow,
/// float powf(float x, float y); /// float powf(float x, float y);
powf, powf,
/// long double powl(long double x, long double y); /// long double powl(long double x, long double y);
powl, powl,
/// double rint(double x);
rint,
/// float rintf(float x);
rintf,
/// long dobule rintl(long double x);
rintl,
/// double sin(double x); /// double sin(double x);
sin, sin,
/// long double sinl(long double x); /// long double sinl(long double x);
@ -175,6 +193,12 @@ namespace llvm {
tanhl, tanhl,
/// float tanhf(float x); /// float tanhf(float x);
tanhf, tanhf,
/// double trunc(double x);
trunc,
/// float truncf(float x);
truncf,
/// long double truncl(long double x);
truncl,
NumLibFuncs NumLibFuncs
}; };

View File

@ -47,6 +47,7 @@
#include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetIntrinsicInfo.h" #include "llvm/Target/TargetIntrinsicInfo.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
@ -812,9 +813,11 @@ void RegsForValue::AddInlineAsmOperands(unsigned Code, bool HasMatching,
} }
} }
void SelectionDAGBuilder::init(GCFunctionInfo *gfi, AliasAnalysis &aa) { void SelectionDAGBuilder::init(GCFunctionInfo *gfi, AliasAnalysis &aa,
const TargetLibraryInfo *li) {
AA = &aa; AA = &aa;
GFI = gfi; GFI = gfi;
LibInfo = li;
TD = DAG.getTarget().getTargetData(); TD = DAG.getTarget().getTargetData();
LPadToCallSiteMap.clear(); LPadToCallSiteMap.clear();
} }
@ -5509,7 +5512,9 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
// can't be a library call. // can't be a library call.
if (!F->hasLocalLinkage() && F->hasName()) { if (!F->hasLocalLinkage() && F->hasName()) {
StringRef Name = F->getName(); StringRef Name = F->getName();
if (Name == "copysign" || Name == "copysignf" || Name == "copysignl") { if ((LibInfo->has(LibFunc::copysign) && Name == "copysign") ||
(LibInfo->has(LibFunc::copysignf) && Name == "copysignf") ||
(LibInfo->has(LibFunc::copysignl) && Name == "copysignl")) {
if (I.getNumArgOperands() == 2 && // Basic sanity checks. if (I.getNumArgOperands() == 2 && // Basic sanity checks.
I.getArgOperand(0)->getType()->isFloatingPointTy() && I.getArgOperand(0)->getType()->isFloatingPointTy() &&
I.getType() == I.getArgOperand(0)->getType() && I.getType() == I.getArgOperand(0)->getType() &&
@ -5520,7 +5525,9 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
LHS.getValueType(), LHS, RHS)); LHS.getValueType(), LHS, RHS));
return; return;
} }
} else if (Name == "fabs" || Name == "fabsf" || Name == "fabsl") { } else if ((LibInfo->has(LibFunc::fabs) && Name == "fabs") ||
(LibInfo->has(LibFunc::fabsf) && Name == "fabsf") ||
(LibInfo->has(LibFunc::fabsl) && Name == "fabsl")) {
if (I.getNumArgOperands() == 1 && // Basic sanity checks. if (I.getNumArgOperands() == 1 && // Basic sanity checks.
I.getArgOperand(0)->getType()->isFloatingPointTy() && I.getArgOperand(0)->getType()->isFloatingPointTy() &&
I.getType() == I.getArgOperand(0)->getType()) { I.getType() == I.getArgOperand(0)->getType()) {
@ -5529,7 +5536,9 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
Tmp.getValueType(), Tmp)); Tmp.getValueType(), Tmp));
return; return;
} }
} else if (Name == "sin" || Name == "sinf" || Name == "sinl") { } else if ((LibInfo->has(LibFunc::sin) && Name == "sin") ||
(LibInfo->has(LibFunc::sinf) && Name == "sinf") ||
(LibInfo->has(LibFunc::sinl) && Name == "sinl")) {
if (I.getNumArgOperands() == 1 && // Basic sanity checks. if (I.getNumArgOperands() == 1 && // Basic sanity checks.
I.getArgOperand(0)->getType()->isFloatingPointTy() && I.getArgOperand(0)->getType()->isFloatingPointTy() &&
I.getType() == I.getArgOperand(0)->getType() && I.getType() == I.getArgOperand(0)->getType() &&
@ -5539,7 +5548,9 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
Tmp.getValueType(), Tmp)); Tmp.getValueType(), Tmp));
return; return;
} }
} else if (Name == "cos" || Name == "cosf" || Name == "cosl") { } else if ((LibInfo->has(LibFunc::cos) && Name == "cos") ||
(LibInfo->has(LibFunc::cosf) && Name == "cosf") ||
(LibInfo->has(LibFunc::cosl) && Name == "cosl")) {
if (I.getNumArgOperands() == 1 && // Basic sanity checks. if (I.getNumArgOperands() == 1 && // Basic sanity checks.
I.getArgOperand(0)->getType()->isFloatingPointTy() && I.getArgOperand(0)->getType()->isFloatingPointTy() &&
I.getType() == I.getArgOperand(0)->getType() && I.getType() == I.getArgOperand(0)->getType() &&
@ -5549,7 +5560,9 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
Tmp.getValueType(), Tmp)); Tmp.getValueType(), Tmp));
return; return;
} }
} else if (Name == "sqrt" || Name == "sqrtf" || Name == "sqrtl") { } else if ((LibInfo->has(LibFunc::sqrt) && Name == "sqrt") ||
(LibInfo->has(LibFunc::sqrtf) && Name == "sqrtf") ||
(LibInfo->has(LibFunc::sqrtl) && Name == "sqrtl")) {
if (I.getNumArgOperands() == 1 && // Basic sanity checks. if (I.getNumArgOperands() == 1 && // Basic sanity checks.
I.getArgOperand(0)->getType()->isFloatingPointTy() && I.getArgOperand(0)->getType()->isFloatingPointTy() &&
I.getType() == I.getArgOperand(0)->getType() && I.getType() == I.getArgOperand(0)->getType() &&
@ -5559,7 +5572,9 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
Tmp.getValueType(), Tmp)); Tmp.getValueType(), Tmp));
return; return;
} }
} else if (Name == "floor" || Name == "floorf" || Name == "floorl") { } else if ((LibInfo->has(LibFunc::floor) && Name == "floor") ||
(LibInfo->has(LibFunc::floorf) && Name == "floorf") ||
(LibInfo->has(LibFunc::floorl) && Name == "floorl")) {
if (I.getNumArgOperands() == 1 && // Basic sanity checks. if (I.getNumArgOperands() == 1 && // Basic sanity checks.
I.getArgOperand(0)->getType()->isFloatingPointTy() && I.getArgOperand(0)->getType()->isFloatingPointTy() &&
I.getType() == I.getArgOperand(0)->getType()) { I.getType() == I.getArgOperand(0)->getType()) {
@ -5568,8 +5583,9 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
Tmp.getValueType(), Tmp)); Tmp.getValueType(), Tmp));
return; return;
} }
} else if (Name == "nearbyint" || Name == "nearbyintf" || } else if ((LibInfo->has(LibFunc::nearbyint) && Name == "nearbyint") ||
Name == "nearbyintl") { (LibInfo->has(LibFunc::nearbyintf) && Name == "nearbyintf") ||
(LibInfo->has(LibFunc::nearbyintl) && Name == "nearbyintl")) {
if (I.getNumArgOperands() == 1 && // Basic sanity checks. if (I.getNumArgOperands() == 1 && // Basic sanity checks.
I.getArgOperand(0)->getType()->isFloatingPointTy() && I.getArgOperand(0)->getType()->isFloatingPointTy() &&
I.getType() == I.getArgOperand(0)->getType()) { I.getType() == I.getArgOperand(0)->getType()) {
@ -5578,7 +5594,9 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
Tmp.getValueType(), Tmp)); Tmp.getValueType(), Tmp));
return; return;
} }
} else if (Name == "ceil" || Name == "ceilf" || Name == "ceill") { } else if ((LibInfo->has(LibFunc::ceil) && Name == "ceil") ||
(LibInfo->has(LibFunc::ceilf) && Name == "ceilf") ||
(LibInfo->has(LibFunc::ceill) && Name == "ceill")) {
if (I.getNumArgOperands() == 1 && // Basic sanity checks. if (I.getNumArgOperands() == 1 && // Basic sanity checks.
I.getArgOperand(0)->getType()->isFloatingPointTy() && I.getArgOperand(0)->getType()->isFloatingPointTy() &&
I.getType() == I.getArgOperand(0)->getType()) { I.getType() == I.getArgOperand(0)->getType()) {
@ -5587,7 +5605,9 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
Tmp.getValueType(), Tmp)); Tmp.getValueType(), Tmp));
return; return;
} }
} else if (Name == "rint" || Name == "rintf" || Name == "rintl") { } else if ((LibInfo->has(LibFunc::rint) && Name == "rint") ||
(LibInfo->has(LibFunc::rintf) && Name == "rintf") ||
(LibInfo->has(LibFunc::rintl) && Name == "rintl")) {
if (I.getNumArgOperands() == 1 && // Basic sanity checks. if (I.getNumArgOperands() == 1 && // Basic sanity checks.
I.getArgOperand(0)->getType()->isFloatingPointTy() && I.getArgOperand(0)->getType()->isFloatingPointTy() &&
I.getType() == I.getArgOperand(0)->getType()) { I.getType() == I.getArgOperand(0)->getType()) {
@ -5596,7 +5616,9 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
Tmp.getValueType(), Tmp)); Tmp.getValueType(), Tmp));
return; return;
} }
} else if (Name == "trunc" || Name == "truncf" || Name == "truncl") { } else if ((LibInfo->has(LibFunc::trunc) && Name == "trunc") ||
(LibInfo->has(LibFunc::truncf) && Name == "truncf") ||
(LibInfo->has(LibFunc::truncl) && Name == "truncl")) {
if (I.getNumArgOperands() == 1 && // Basic sanity checks. if (I.getNumArgOperands() == 1 && // Basic sanity checks.
I.getArgOperand(0)->getType()->isFloatingPointTy() && I.getArgOperand(0)->getType()->isFloatingPointTy() &&
I.getType() == I.getArgOperand(0)->getType()) { I.getType() == I.getArgOperand(0)->getType()) {
@ -5605,7 +5627,6 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
Tmp.getValueType(), Tmp)); Tmp.getValueType(), Tmp));
return; return;
} }
} else if (Name == "memcmp") { } else if (Name == "memcmp") {
if (visitMemCmpCall(I)) if (visitMemCmpCall(I))
return; return;

View File

@ -67,6 +67,7 @@ class SIToFPInst;
class StoreInst; class StoreInst;
class SwitchInst; class SwitchInst;
class TargetData; class TargetData;
class TargetLibraryInfo;
class TargetLowering; class TargetLowering;
class TruncInst; class TruncInst;
class UIToFPInst; class UIToFPInst;
@ -294,6 +295,7 @@ public:
SelectionDAG &DAG; SelectionDAG &DAG;
const TargetData *TD; const TargetData *TD;
AliasAnalysis *AA; AliasAnalysis *AA;
const TargetLibraryInfo *LibInfo;
/// SwitchCases - Vector of CaseBlock structures used to communicate /// SwitchCases - Vector of CaseBlock structures used to communicate
/// SwitchInst code generation information. /// SwitchInst code generation information.
@ -338,7 +340,8 @@ public:
HasTailCall(false), Context(dag.getContext()) { HasTailCall(false), Context(dag.getContext()) {
} }
void init(GCFunctionInfo *gfi, AliasAnalysis &aa); void init(GCFunctionInfo *gfi, AliasAnalysis &aa,
const TargetLibraryInfo *li);
/// clear - Clear out the current SelectionDAG and the associated /// clear - Clear out the current SelectionDAG and the associated
/// state and prepare this SelectionDAGBuilder object to be used /// state and prepare this SelectionDAGBuilder object to be used

View File

@ -41,6 +41,7 @@
#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetIntrinsicInfo.h" #include "llvm/Target/TargetIntrinsicInfo.h"
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetOptions.h"
@ -269,6 +270,7 @@ SelectionDAGISel::SelectionDAGISel(const TargetMachine &tm,
initializeGCModuleInfoPass(*PassRegistry::getPassRegistry()); initializeGCModuleInfoPass(*PassRegistry::getPassRegistry());
initializeAliasAnalysisAnalysisGroup(*PassRegistry::getPassRegistry()); initializeAliasAnalysisAnalysisGroup(*PassRegistry::getPassRegistry());
initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry()); initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry());
initializeTargetLibraryInfoPass(*PassRegistry::getPassRegistry());
} }
SelectionDAGISel::~SelectionDAGISel() { SelectionDAGISel::~SelectionDAGISel() {
@ -282,6 +284,7 @@ void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addPreserved<AliasAnalysis>(); AU.addPreserved<AliasAnalysis>();
AU.addRequired<GCModuleInfo>(); AU.addRequired<GCModuleInfo>();
AU.addPreserved<GCModuleInfo>(); AU.addPreserved<GCModuleInfo>();
AU.addRequired<TargetLibraryInfo>();
if (UseMBPI && OptLevel != CodeGenOpt::None) if (UseMBPI && OptLevel != CodeGenOpt::None)
AU.addRequired<BranchProbabilityInfo>(); AU.addRequired<BranchProbabilityInfo>();
MachineFunctionPass::getAnalysisUsage(AU); MachineFunctionPass::getAnalysisUsage(AU);
@ -339,6 +342,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
MF = &mf; MF = &mf;
RegInfo = &MF->getRegInfo(); RegInfo = &MF->getRegInfo();
AA = &getAnalysis<AliasAnalysis>(); AA = &getAnalysis<AliasAnalysis>();
LibInfo = &getAnalysis<TargetLibraryInfo>();
GFI = Fn.hasGC() ? &getAnalysis<GCModuleInfo>().getFunctionInfo(Fn) : 0; GFI = Fn.hasGC() ? &getAnalysis<GCModuleInfo>().getFunctionInfo(Fn) : 0;
DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n"); DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n");
@ -353,7 +357,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
else else
FuncInfo->BPI = 0; FuncInfo->BPI = 0;
SDB->init(GFI, *AA); SDB->init(GFI, *AA, LibInfo);
SelectAllBasicBlocks(Fn); SelectAllBasicBlocks(Fn);

View File

@ -37,6 +37,9 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] =
"ceil", "ceil",
"ceill", "ceill",
"ceilf", "ceilf",
"copysign",
"copysignf",
"copysignl",
"cos", "cos",
"cosl", "cosl",
"cosf", "cosf",
@ -81,9 +84,15 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] =
"memmove", "memmove",
"memset", "memset",
"memset_pattern16", "memset_pattern16",
"nearbyint",
"nearbyintf",
"nearbyintl",
"pow", "pow",
"powf", "powf",
"powl", "powl",
"rint",
"rintf",
"rintl",
"sin", "sin",
"sinl", "sinl",
"sinf", "sinf",
@ -99,7 +108,10 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] =
"tanf", "tanf",
"tanh", "tanh",
"tanhl", "tanhl",
"tanhf" "tanhf",
"trunc",
"truncf",
"truncl"
}; };
/// initialize - Initialize the set of available library functions based on the /// initialize - Initialize the set of available library functions based on the