mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-12 20:48:17 +00:00
Refactor intrinsic lowering stuff out of visitCall
llvm-svn: 24261
This commit is contained in:
parent
1acb71df32
commit
11d12a572e
@ -46,7 +46,6 @@ ViewDAGs("view-isel-dags", cl::Hidden,
|
|||||||
static const bool ViewDAGs = 0;
|
static const bool ViewDAGs = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
/// FunctionLoweringInfo - This contains information that is global to a
|
/// FunctionLoweringInfo - This contains information that is global to a
|
||||||
@ -405,6 +404,7 @@ public:
|
|||||||
void visitStore(StoreInst &I);
|
void visitStore(StoreInst &I);
|
||||||
void visitPHI(PHINode &I) { } // PHI nodes are handled specially.
|
void visitPHI(PHINode &I) { } // PHI nodes are handled specially.
|
||||||
void visitCall(CallInst &I);
|
void visitCall(CallInst &I);
|
||||||
|
const char *visitIntrinsicCall(CallInst &I, unsigned Intrinsic);
|
||||||
|
|
||||||
void visitVAStart(CallInst &I);
|
void visitVAStart(CallInst &I);
|
||||||
void visitVAArg(VAArgInst &I);
|
void visitVAArg(VAArgInst &I);
|
||||||
@ -737,56 +737,26 @@ void SelectionDAGLowering::visitStore(StoreInst &I) {
|
|||||||
DAG.getSrcValue(I.getOperand(1))));
|
DAG.getSrcValue(I.getOperand(1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectionDAGLowering::visitCall(CallInst &I) {
|
/// visitIntrinsicCall - Lower the call to the specified intrinsic function. If
|
||||||
const char *RenameFn = 0;
|
/// we want to emit this as a call to a named external function, return the name
|
||||||
SDOperand Tmp;
|
/// otherwise lower it and return null.
|
||||||
if (Function *F = I.getCalledFunction())
|
const char *
|
||||||
if (F->isExternal())
|
SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||||
switch (F->getIntrinsicID()) {
|
switch (Intrinsic) {
|
||||||
case 0: // Not an LLVM intrinsic.
|
case Intrinsic::vastart: visitVAStart(I); return 0;
|
||||||
if (F->getName() == "fabs" || F->getName() == "fabsf") {
|
case Intrinsic::vaend: visitVAEnd(I); return 0;
|
||||||
if (I.getNumOperands() == 2 && // Basic sanity checks.
|
case Intrinsic::vacopy: visitVACopy(I); return 0;
|
||||||
I.getOperand(1)->getType()->isFloatingPoint() &&
|
case Intrinsic::returnaddress: visitFrameReturnAddress(I, false); return 0;
|
||||||
I.getType() == I.getOperand(1)->getType()) {
|
case Intrinsic::frameaddress: visitFrameReturnAddress(I, true); return 0;
|
||||||
Tmp = getValue(I.getOperand(1));
|
|
||||||
setValue(&I, DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (F->getName() == "sin" || F->getName() == "sinf") {
|
|
||||||
if (I.getNumOperands() == 2 && // Basic sanity checks.
|
|
||||||
I.getOperand(1)->getType()->isFloatingPoint() &&
|
|
||||||
I.getType() == I.getOperand(1)->getType()) {
|
|
||||||
Tmp = getValue(I.getOperand(1));
|
|
||||||
setValue(&I, DAG.getNode(ISD::FSIN, Tmp.getValueType(), Tmp));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (F->getName() == "cos" || F->getName() == "cosf") {
|
|
||||||
if (I.getNumOperands() == 2 && // Basic sanity checks.
|
|
||||||
I.getOperand(1)->getType()->isFloatingPoint() &&
|
|
||||||
I.getType() == I.getOperand(1)->getType()) {
|
|
||||||
Tmp = getValue(I.getOperand(1));
|
|
||||||
setValue(&I, DAG.getNode(ISD::FCOS, Tmp.getValueType(), Tmp));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Intrinsic::vastart: visitVAStart(I); return;
|
|
||||||
case Intrinsic::vaend: visitVAEnd(I); return;
|
|
||||||
case Intrinsic::vacopy: visitVACopy(I); return;
|
|
||||||
case Intrinsic::returnaddress: visitFrameReturnAddress(I, false); return;
|
|
||||||
case Intrinsic::frameaddress: visitFrameReturnAddress(I, true); return;
|
|
||||||
|
|
||||||
case Intrinsic::setjmp:
|
case Intrinsic::setjmp:
|
||||||
RenameFn = "_setjmp"+!TLI.usesUnderscoreSetJmpLongJmp();
|
return "_setjmp"+!TLI.usesUnderscoreSetJmpLongJmp();
|
||||||
break;
|
break;
|
||||||
case Intrinsic::longjmp:
|
case Intrinsic::longjmp:
|
||||||
RenameFn = "_longjmp"+!TLI.usesUnderscoreSetJmpLongJmp();
|
return "_longjmp"+!TLI.usesUnderscoreSetJmpLongJmp();
|
||||||
break;
|
break;
|
||||||
case Intrinsic::memcpy: visitMemIntrinsic(I, ISD::MEMCPY); return;
|
case Intrinsic::memcpy: visitMemIntrinsic(I, ISD::MEMCPY); return 0;
|
||||||
case Intrinsic::memset: visitMemIntrinsic(I, ISD::MEMSET); return;
|
case Intrinsic::memset: visitMemIntrinsic(I, ISD::MEMSET); return 0;
|
||||||
case Intrinsic::memmove: visitMemIntrinsic(I, ISD::MEMMOVE); return;
|
case Intrinsic::memmove: visitMemIntrinsic(I, ISD::MEMMOVE); return 0;
|
||||||
|
|
||||||
case Intrinsic::readport:
|
case Intrinsic::readport:
|
||||||
case Intrinsic::readio: {
|
case Intrinsic::readio: {
|
||||||
@ -796,20 +766,20 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
|
|||||||
std::vector<SDOperand> Ops;
|
std::vector<SDOperand> Ops;
|
||||||
Ops.push_back(getRoot());
|
Ops.push_back(getRoot());
|
||||||
Ops.push_back(getValue(I.getOperand(1)));
|
Ops.push_back(getValue(I.getOperand(1)));
|
||||||
Tmp = DAG.getNode(F->getIntrinsicID() == Intrinsic::readport ?
|
SDOperand Tmp = DAG.getNode(Intrinsic == Intrinsic::readport ?
|
||||||
ISD::READPORT : ISD::READIO, VTs, Ops);
|
ISD::READPORT : ISD::READIO, VTs, Ops);
|
||||||
|
|
||||||
setValue(&I, Tmp);
|
setValue(&I, Tmp);
|
||||||
DAG.setRoot(Tmp.getValue(1));
|
DAG.setRoot(Tmp.getValue(1));
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
case Intrinsic::writeport:
|
case Intrinsic::writeport:
|
||||||
case Intrinsic::writeio:
|
case Intrinsic::writeio:
|
||||||
DAG.setRoot(DAG.getNode(F->getIntrinsicID() == Intrinsic::writeport ?
|
DAG.setRoot(DAG.getNode(Intrinsic == Intrinsic::writeport ?
|
||||||
ISD::WRITEPORT : ISD::WRITEIO, MVT::Other,
|
ISD::WRITEPORT : ISD::WRITEIO, MVT::Other,
|
||||||
getRoot(), getValue(I.getOperand(1)),
|
getRoot(), getValue(I.getOperand(1)),
|
||||||
getValue(I.getOperand(2))));
|
getValue(I.getOperand(2))));
|
||||||
return;
|
return 0;
|
||||||
case Intrinsic::dbg_stoppoint:
|
case Intrinsic::dbg_stoppoint:
|
||||||
case Intrinsic::dbg_region_start:
|
case Intrinsic::dbg_region_start:
|
||||||
case Intrinsic::dbg_region_end:
|
case Intrinsic::dbg_region_end:
|
||||||
@ -817,42 +787,82 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
|
|||||||
case Intrinsic::dbg_declare:
|
case Intrinsic::dbg_declare:
|
||||||
if (I.getType() != Type::VoidTy)
|
if (I.getType() != Type::VoidTy)
|
||||||
setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType())));
|
setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType())));
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
case Intrinsic::isunordered:
|
case Intrinsic::isunordered:
|
||||||
setValue(&I, DAG.getSetCC(MVT::i1,getValue(I.getOperand(1)),
|
setValue(&I, DAG.getSetCC(MVT::i1,getValue(I.getOperand(1)),
|
||||||
getValue(I.getOperand(2)), ISD::SETUO));
|
getValue(I.getOperand(2)), ISD::SETUO));
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
case Intrinsic::sqrt:
|
case Intrinsic::sqrt:
|
||||||
setValue(&I, DAG.getNode(ISD::FSQRT,
|
setValue(&I, DAG.getNode(ISD::FSQRT,
|
||||||
getValue(I.getOperand(1)).getValueType(),
|
getValue(I.getOperand(1)).getValueType(),
|
||||||
getValue(I.getOperand(1))));
|
getValue(I.getOperand(1))));
|
||||||
return;
|
return 0;
|
||||||
|
case Intrinsic::pcmarker: {
|
||||||
case Intrinsic::pcmarker:
|
SDOperand Tmp = getValue(I.getOperand(1));
|
||||||
Tmp = getValue(I.getOperand(1));
|
|
||||||
DAG.setRoot(DAG.getNode(ISD::PCMARKER, MVT::Other, getRoot(), Tmp));
|
DAG.setRoot(DAG.getNode(ISD::PCMARKER, MVT::Other, getRoot(), Tmp));
|
||||||
return;
|
return 0;
|
||||||
|
}
|
||||||
case Intrinsic::cttz:
|
case Intrinsic::cttz:
|
||||||
setValue(&I, DAG.getNode(ISD::CTTZ,
|
setValue(&I, DAG.getNode(ISD::CTTZ,
|
||||||
getValue(I.getOperand(1)).getValueType(),
|
getValue(I.getOperand(1)).getValueType(),
|
||||||
getValue(I.getOperand(1))));
|
getValue(I.getOperand(1))));
|
||||||
return;
|
return 0;
|
||||||
case Intrinsic::ctlz:
|
case Intrinsic::ctlz:
|
||||||
setValue(&I, DAG.getNode(ISD::CTLZ,
|
setValue(&I, DAG.getNode(ISD::CTLZ,
|
||||||
getValue(I.getOperand(1)).getValueType(),
|
getValue(I.getOperand(1)).getValueType(),
|
||||||
getValue(I.getOperand(1))));
|
getValue(I.getOperand(1))));
|
||||||
return;
|
return 0;
|
||||||
case Intrinsic::ctpop:
|
case Intrinsic::ctpop:
|
||||||
setValue(&I, DAG.getNode(ISD::CTPOP,
|
setValue(&I, DAG.getNode(ISD::CTPOP,
|
||||||
getValue(I.getOperand(1)).getValueType(),
|
getValue(I.getOperand(1)).getValueType(),
|
||||||
getValue(I.getOperand(1))));
|
getValue(I.getOperand(1))));
|
||||||
return;
|
return 0;
|
||||||
default:
|
default:
|
||||||
std::cerr << I;
|
std::cerr << I;
|
||||||
assert(0 && "This intrinsic is not implemented yet!");
|
assert(0 && "This intrinsic is not implemented yet!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SelectionDAGLowering::visitCall(CallInst &I) {
|
||||||
|
const char *RenameFn = 0;
|
||||||
|
if (Function *F = I.getCalledFunction()) {
|
||||||
|
if (F->isExternal())
|
||||||
|
if (unsigned IID = F->getIntrinsicID()) {
|
||||||
|
RenameFn = visitIntrinsicCall(I, IID);
|
||||||
|
if (!RenameFn)
|
||||||
return;
|
return;
|
||||||
|
} else { // Not an LLVM intrinsic.
|
||||||
|
const std::string &Name = F->getName();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDOperand Callee;
|
SDOperand Callee;
|
||||||
@ -861,7 +871,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
|
|||||||
else
|
else
|
||||||
Callee = DAG.getExternalSymbol(RenameFn, TLI.getPointerTy());
|
Callee = DAG.getExternalSymbol(RenameFn, TLI.getPointerTy());
|
||||||
std::vector<std::pair<SDOperand, const Type*> > Args;
|
std::vector<std::pair<SDOperand, const Type*> > Args;
|
||||||
|
Args.reserve(I.getNumOperands());
|
||||||
for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
|
for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
|
||||||
Value *Arg = I.getOperand(i);
|
Value *Arg = I.getOperand(i);
|
||||||
SDOperand ArgNode = getValue(Arg);
|
SDOperand ArgNode = getValue(Arg);
|
||||||
@ -1045,7 +1055,6 @@ void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
|
|||||||
// updates dom and loop info.
|
// updates dom and loop info.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SelectionDAGISel::runOnFunction(Function &Fn) {
|
bool SelectionDAGISel::runOnFunction(Function &Fn) {
|
||||||
MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine());
|
MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine());
|
||||||
RegMap = MF.getSSARegMap();
|
RegMap = MF.getSSARegMap();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user