From 39ae3622791986a0232f7e4797b633f8fa9e54d2 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 9 Jan 2005 00:00:49 +0000 Subject: [PATCH] Use new interfaces to correctly lower varargs and return/frame address intrinsics. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19407 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 94 +++++++++++++------ 1 file changed, 65 insertions(+), 29 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index f6d497988fc..4fe5ddf3335 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -304,14 +304,12 @@ public: void visitPHI(PHINode &I) { } // PHI nodes are handled specially. void visitCall(CallInst &I); - // FIXME: These should go through the FunctionLoweringInfo object!!! void visitVAStart(CallInst &I); void visitVANext(VANextInst &I); void visitVAArg(VAArgInst &I); void visitVAEnd(CallInst &I); void visitVACopy(CallInst &I); - void visitReturnAddress(CallInst &I); - void visitFrameAddress(CallInst &I); + void visitFrameReturnAddress(CallInst &I, bool isFrameAddress); void visitMemSet(CallInst &I); void visitMemCpy(CallInst &I); @@ -576,10 +574,8 @@ void SelectionDAGLowering::visitCall(CallInst &I) { case Intrinsic::vastart: visitVAStart(I); return; case Intrinsic::vaend: visitVAEnd(I); return; case Intrinsic::vacopy: visitVACopy(I); return; - case Intrinsic::returnaddress: - visitReturnAddress(I); return; - case Intrinsic::frameaddress: - visitFrameAddress(I); return; + case Intrinsic::returnaddress: visitFrameReturnAddress(I, false); return; + case Intrinsic::frameaddress: visitFrameReturnAddress(I, true); return; default: // FIXME: IMPLEMENT THESE. // readport, writeport, readio, writeio @@ -651,46 +647,86 @@ void SelectionDAGLowering::visitFree(FreeInst &I) { DAG.setRoot(Result.second); } -void SelectionDAGLowering::visitVAStart(CallInst &I) { +std::pair +TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) { // We have no sane default behavior, just emit a useful error message and bail // out. - std::cerr << "Variable arguments support not implemented for this target!\n"; + std::cerr << "Variable arguments handling not implemented on this target!\n"; abort(); } +SDOperand TargetLowering::LowerVAEnd(SDOperand Chain, SDOperand L, + SelectionDAG &DAG) { + // Default to a noop. + return Chain; +} + +std::pair +TargetLowering::LowerVACopy(SDOperand Chain, SDOperand L, SelectionDAG &DAG) { + // Default to returning the input list. + return std::make_pair(L, Chain); +} + +std::pair +TargetLowering::LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, + const Type *ArgTy, SelectionDAG &DAG) { + // We have no sane default behavior, just emit a useful error message and bail + // out. + std::cerr << "Variable arguments handling not implemented on this target!\n"; + abort(); +} + + +void SelectionDAGLowering::visitVAStart(CallInst &I) { + std::pair Result = TLI.LowerVAStart(DAG.getRoot(), DAG); + setValue(&I, Result.first); + DAG.setRoot(Result.second); +} + +void SelectionDAGLowering::visitVAArg(VAArgInst &I) { + std::pair Result = + TLI.LowerVAArgNext(false, DAG.getRoot(), getValue(I.getOperand(0)), + I.getType(), DAG); + setValue(&I, Result.first); + DAG.setRoot(Result.second); +} + void SelectionDAGLowering::visitVANext(VANextInst &I) { - // We have no sane default behavior, just emit a useful error message and bail - // out. - std::cerr << "Variable arguments support not implemented for this target!\n"; - abort(); -} -void SelectionDAGLowering::visitVAArg(VAArgInst &I) { - // We have no sane default behavior, just emit a useful error message and bail - // out. - std::cerr << "Variable arguments support not implemented for this target!\n"; - abort(); + std::pair Result = + TLI.LowerVAArgNext(true, DAG.getRoot(), getValue(I.getOperand(0)), + I.getArgType(), DAG); + setValue(&I, Result.first); + DAG.setRoot(Result.second); } void SelectionDAGLowering::visitVAEnd(CallInst &I) { - // By default, this is a noop. On almost all targets, this is fine. + DAG.setRoot(TLI.LowerVAEnd(DAG.getRoot(), getValue(I.getOperand(1)), DAG)); } void SelectionDAGLowering::visitVACopy(CallInst &I) { - // By default, vacopy just does a simple pointer copy. - setValue(&I, getValue(I.getOperand(1))); + std::pair Result = + TLI.LowerVACopy(DAG.getRoot(), getValue(I.getOperand(1)), DAG); + setValue(&I, Result.first); + DAG.setRoot(Result.second); } -void SelectionDAGLowering::visitReturnAddress(CallInst &I) { - // It is always conservatively correct for llvm.returnaddress to return 0. - setValue(&I, getIntPtrConstant(0)); + +// It is always conservatively correct for llvm.returnaddress and +// llvm.frameaddress to return 0. +std::pair +TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, + unsigned Depth, SelectionDAG &DAG) { + return std::make_pair(DAG.getConstant(0, getPointerTy()), Chain); } -void SelectionDAGLowering::visitFrameAddress(CallInst &I) { - // It is always conservatively correct for llvm.frameaddress to return 0. - setValue(&I, getIntPtrConstant(0)); +void SelectionDAGLowering::visitFrameReturnAddress(CallInst &I, bool isFrame) { + unsigned Depth = (unsigned)cast(I.getOperand(1))->getValue(); + std::pair Result = + TLI.LowerFrameReturnAddress(isFrame, DAG.getRoot(), Depth, DAG); + setValue(&I, Result.first); + DAG.setRoot(Result.second); } - void SelectionDAGLowering::visitMemSet(CallInst &I) { MVT::ValueType IntPtr = TLI.getPointerTy(); const Type *IntPtrTy = TLI.getTargetData().getIntPtrType();