Refactor intrinsic lowering stuff out of visitCall

llvm-svn: 24261
This commit is contained in:
Chris Lattner 2005-11-09 19:44:01 +00:00
parent 1acb71df32
commit 11d12a572e

View File

@ -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();