forked from OSchip/llvm-project
Finish off bug 680, allowing targets to custom lower frame and return
address nodes. llvm-svn: 33636
This commit is contained in:
parent
e3b09fbbb0
commit
eda5997cc8
|
@ -84,6 +84,13 @@ namespace ISD {
|
|||
|
||||
// The address of the GOT
|
||||
GLOBAL_OFFSET_TABLE,
|
||||
|
||||
// FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and
|
||||
// llvm.returnaddress on the DAG. These nodes take one operand, the index
|
||||
// of the frame or return address to return. An index of zero corresponds
|
||||
// to the current function's frame or return address, an index of one to the
|
||||
// parent's frame or return address, and so on.
|
||||
FRAMEADDR, RETURNADDR,
|
||||
|
||||
// TargetConstant* - Like Constant*, but the DAG does not do any folding or
|
||||
// simplification of the constant.
|
||||
|
|
|
@ -739,14 +739,6 @@ public:
|
|||
bool isVarArg, unsigned CallingConv, bool isTailCall,
|
||||
SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
|
||||
|
||||
/// LowerFrameReturnAddress - This hook lowers a call to llvm.returnaddress or
|
||||
/// llvm.frameaddress (depending on the value of the first argument). The
|
||||
/// return values are the result pointer and the resultant token chain. If
|
||||
/// not implemented, both of these intrinsics will return null.
|
||||
virtual std::pair<SDOperand, SDOperand>
|
||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
/// LowerOperation - This callback is invoked for operations that are
|
||||
/// unsupported by the target, which are registered to use 'custom' lowering,
|
||||
/// and whose defined values are all legal.
|
||||
|
|
|
@ -652,6 +652,16 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case ISD::FRAMEADDR:
|
||||
case ISD::RETURNADDR:
|
||||
// The only option for these nodes is to custom lower them. If the target
|
||||
// does not custom lower them, then return zero.
|
||||
Tmp1 = TLI.LowerOperation(Op, DAG);
|
||||
if (Tmp1.Val)
|
||||
Result = Tmp1;
|
||||
else
|
||||
Result = DAG.getConstant(0, TLI.getPointerTy());
|
||||
break;
|
||||
case ISD::AssertSext:
|
||||
case ISD::AssertZext:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0));
|
||||
|
|
|
@ -2665,6 +2665,8 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
|
|||
case ISD::FrameIndex: return "FrameIndex";
|
||||
case ISD::JumpTable: return "JumpTable";
|
||||
case ISD::GLOBAL_OFFSET_TABLE: return "GLOBAL_OFFSET_TABLE";
|
||||
case ISD::RETURNADDR: return "RETURNADDR";
|
||||
case ISD::FRAMEADDR: return "FRAMEADDR";
|
||||
case ISD::ConstantPool: return "ConstantPool";
|
||||
case ISD::ExternalSymbol: return "ExternalSymbol";
|
||||
case ISD::INTRINSIC_WO_CHAIN: {
|
||||
|
|
|
@ -570,7 +570,6 @@ public:
|
|||
void visitVAArg(VAArgInst &I);
|
||||
void visitVAEnd(CallInst &I);
|
||||
void visitVACopy(CallInst &I);
|
||||
void visitFrameReturnAddress(CallInst &I, bool isFrameAddress);
|
||||
|
||||
void visitMemIntrinsic(CallInst &I, unsigned Op);
|
||||
|
||||
|
@ -1932,8 +1931,14 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
|||
case Intrinsic::vastart: visitVAStart(I); return 0;
|
||||
case Intrinsic::vaend: visitVAEnd(I); return 0;
|
||||
case Intrinsic::vacopy: visitVACopy(I); return 0;
|
||||
case Intrinsic::returnaddress: visitFrameReturnAddress(I, false); return 0;
|
||||
case Intrinsic::frameaddress: visitFrameReturnAddress(I, true); return 0;
|
||||
case Intrinsic::returnaddress:
|
||||
setValue(&I, DAG.getNode(ISD::RETURNADDR, TLI.getPointerTy(),
|
||||
getValue(I.getOperand(1))));
|
||||
return 0;
|
||||
case Intrinsic::frameaddress:
|
||||
setValue(&I, DAG.getNode(ISD::FRAMEADDR, TLI.getPointerTy(),
|
||||
getValue(I.getOperand(1))));
|
||||
return 0;
|
||||
case Intrinsic::setjmp:
|
||||
return "_setjmp"+!TLI.usesUnderscoreSetJmp();
|
||||
break;
|
||||
|
@ -3207,19 +3212,6 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||
return std::make_pair(ResVal, Res.getValue(Res.Val->getNumValues()-1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// It is always conservatively correct for llvm.returnaddress and
|
||||
// llvm.frameaddress to return 0.
|
||||
//
|
||||
// FIXME: Change this to insert a FRAMEADDR/RETURNADDR node, and have that be
|
||||
// expanded to 0 if the target wants.
|
||||
std::pair<SDOperand, SDOperand>
|
||||
TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain,
|
||||
unsigned Depth, SelectionDAG &DAG) {
|
||||
return std::make_pair(DAG.getConstant(0, getPointerTy()), Chain);
|
||||
}
|
||||
|
||||
SDOperand TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
assert(0 && "LowerOperation not implemented for this target!");
|
||||
abort();
|
||||
|
@ -3233,14 +3225,6 @@ SDOperand TargetLowering::CustomPromoteOperation(SDOperand Op,
|
|||
return SDOperand();
|
||||
}
|
||||
|
||||
void SelectionDAGLowering::visitFrameReturnAddress(CallInst &I, bool isFrame) {
|
||||
unsigned Depth = (unsigned)cast<ConstantInt>(I.getOperand(1))->getZExtValue();
|
||||
std::pair<SDOperand,SDOperand> Result =
|
||||
TLI.LowerFrameReturnAddress(isFrame, getRoot(), Depth, DAG);
|
||||
setValue(&I, Result.first);
|
||||
DAG.setRoot(Result.second);
|
||||
}
|
||||
|
||||
/// getMemsetValue - Vectorized representation of the memset value
|
||||
/// operand.
|
||||
static SDOperand getMemsetValue(SDOperand Value, MVT::ValueType VT,
|
||||
|
|
|
@ -1130,7 +1130,10 @@ SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||
case ISD::SRA: return LowerSRx(Op, DAG, Subtarget);
|
||||
case ISD::FORMAL_ARGUMENTS:
|
||||
return LowerFORMAL_ARGUMENTS(Op, DAG);
|
||||
case ISD::RETURNADDR: break;
|
||||
case ISD::FRAMEADDR: break;
|
||||
}
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -544,6 +544,9 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||
return DAG.getTruncStore(S1, DAG.getConstant(VarArgsOffset, MVT::i64),
|
||||
SA2, NULL, 0, MVT::i32);
|
||||
}
|
||||
// Frame & Return address. Currently unimplemented
|
||||
case ISD::RETURNADDR: break;
|
||||
case ISD::FRAMEADDR: break;
|
||||
}
|
||||
|
||||
return SDOperand();
|
||||
|
|
|
@ -532,13 +532,6 @@ IA64TargetLowering::LowerCallTo(SDOperand Chain,
|
|||
return std::make_pair(RetVal, Chain);
|
||||
}
|
||||
|
||||
std::pair<SDOperand, SDOperand> IA64TargetLowering::
|
||||
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG) {
|
||||
assert(0 && "LowerFrameReturnAddress unimplemented");
|
||||
abort();
|
||||
}
|
||||
|
||||
SDOperand IA64TargetLowering::
|
||||
LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
switch (Op.getOpcode()) {
|
||||
|
@ -594,5 +587,9 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||
return DAG.getStore(Op.getOperand(0), FR,
|
||||
Op.getOperand(1), SV->getValue(), SV->getOffset());
|
||||
}
|
||||
// Frame & Return address. Currently unimplemented
|
||||
case ISD::RETURNADDR: break;
|
||||
case ISD::FRAMEADDR: break;
|
||||
}
|
||||
return SDOperand();
|
||||
}
|
||||
|
|
|
@ -66,10 +66,6 @@ namespace llvm {
|
|||
/// (currently, only "ret void")
|
||||
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
|
||||
|
||||
virtual std::pair<SDOperand, SDOperand>
|
||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
// XXX virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
|
||||
// XXX MachineBasicBlock *MBB);
|
||||
};
|
||||
|
|
|
@ -2634,6 +2634,10 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
|
||||
case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG);
|
||||
case ISD::MUL: return LowerMUL(Op, DAG);
|
||||
|
||||
// Frame & Return address. Currently unimplemented
|
||||
case ISD::RETURNADDR: break;
|
||||
case ISD::FRAMEADDR: break;
|
||||
}
|
||||
return SDOperand();
|
||||
}
|
||||
|
|
|
@ -868,7 +868,11 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||
}
|
||||
return DAG.getNode(SPISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
|
||||
}
|
||||
// Frame & Return address. Currently unimplemented
|
||||
case ISD::RETURNADDR: break;
|
||||
case ISD::FRAMEADDR: break;
|
||||
}
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
MachineBasicBlock *
|
||||
|
|
|
@ -1940,25 +1940,6 @@ SDOperand X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
|
|||
|
||||
|
||||
|
||||
std::pair<SDOperand, SDOperand> X86TargetLowering::
|
||||
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG) {
|
||||
SDOperand Result;
|
||||
if (Depth) // Depths > 0 not supported yet!
|
||||
Result = DAG.getConstant(0, getPointerTy());
|
||||
else {
|
||||
SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG);
|
||||
if (!isFrameAddress)
|
||||
// Just load the return address
|
||||
Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), RetAddrFI,
|
||||
NULL, 0);
|
||||
else
|
||||
Result = DAG.getNode(ISD::SUB, getPointerTy(), RetAddrFI,
|
||||
DAG.getConstant(4, getPointerTy()));
|
||||
}
|
||||
return std::make_pair(Result, Chain);
|
||||
}
|
||||
|
||||
/// translateX86CC - do a one to one translation of a ISD::CondCode to the X86
|
||||
/// specific condition code. It returns a false if it cannot do a direct
|
||||
/// translation. X86CC is the translated CondCode. LHS/RHS are modified as
|
||||
|
@ -4621,6 +4602,26 @@ X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG) {
|
|||
}
|
||||
}
|
||||
|
||||
SDOperand X86TargetLowering::LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG) {
|
||||
// Depths > 0 not supported yet!
|
||||
if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
|
||||
return SDOperand();
|
||||
|
||||
// Just load the return address
|
||||
SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG);
|
||||
return DAG.getLoad(getPointerTy(), DAG.getEntryNode(), RetAddrFI, NULL, 0);
|
||||
}
|
||||
|
||||
SDOperand X86TargetLowering::LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG) {
|
||||
// Depths > 0 not supported yet!
|
||||
if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
|
||||
return SDOperand();
|
||||
|
||||
SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG);
|
||||
return DAG.getNode(ISD::SUB, getPointerTy(), RetAddrFI,
|
||||
DAG.getConstant(4, getPointerTy()));
|
||||
}
|
||||
|
||||
/// LowerOperation - Provide custom lowering hooks for some operations.
|
||||
///
|
||||
SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
|
@ -4654,6 +4655,8 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||
case ISD::READCYCLECOUNTER: return LowerREADCYCLCECOUNTER(Op, DAG);
|
||||
case ISD::VASTART: return LowerVASTART(Op, DAG);
|
||||
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
|
||||
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
|
||||
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -292,10 +292,6 @@ namespace llvm {
|
|||
///
|
||||
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
|
||||
|
||||
virtual std::pair<SDOperand, SDOperand>
|
||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
|
||||
|
||||
virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
|
||||
|
@ -406,6 +402,8 @@ namespace llvm {
|
|||
SDOperand LowerREADCYCLCECOUNTER(SDOperand Op, SelectionDAG &DAG);
|
||||
SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG);
|
||||
SDOperand LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG);
|
||||
SDOperand LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG);
|
||||
SDOperand LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue