mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-18 22:38:56 +00:00
Selection and lowering for exception handling.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34481 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c518ccfeb5
commit
b180aa1753
@ -357,6 +357,11 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
|
|||||||
case Intrinsic::dbg_func_start:
|
case Intrinsic::dbg_func_start:
|
||||||
case Intrinsic::dbg_declare:
|
case Intrinsic::dbg_declare:
|
||||||
break; // Simply strip out debugging intrinsics
|
break; // Simply strip out debugging intrinsics
|
||||||
|
|
||||||
|
case Intrinsic::eh_exception:
|
||||||
|
case Intrinsic::eh_handlers:
|
||||||
|
assert(0 && "Should not have leaked through");
|
||||||
|
break;
|
||||||
|
|
||||||
case Intrinsic::memcpy_i32:
|
case Intrinsic::memcpy_i32:
|
||||||
case Intrinsic::memcpy_i64: {
|
case Intrinsic::memcpy_i64: {
|
||||||
|
@ -668,6 +668,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||||||
break;
|
break;
|
||||||
case ISD::FRAMEADDR:
|
case ISD::FRAMEADDR:
|
||||||
case ISD::RETURNADDR:
|
case ISD::RETURNADDR:
|
||||||
|
case ISD::EXCEPTIONADDR:
|
||||||
|
case ISD::EHSELECTION:
|
||||||
// The only option for these nodes is to custom lower them. If the target
|
// The only option for these nodes is to custom lower them. If the target
|
||||||
// does not custom lower them, then return zero.
|
// does not custom lower them, then return zero.
|
||||||
Tmp1 = TLI.LowerOperation(Op, DAG);
|
Tmp1 = TLI.LowerOperation(Op, DAG);
|
||||||
|
@ -2679,6 +2679,8 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
|
|||||||
case ISD::GLOBAL_OFFSET_TABLE: return "GLOBAL_OFFSET_TABLE";
|
case ISD::GLOBAL_OFFSET_TABLE: return "GLOBAL_OFFSET_TABLE";
|
||||||
case ISD::RETURNADDR: return "RETURNADDR";
|
case ISD::RETURNADDR: return "RETURNADDR";
|
||||||
case ISD::FRAMEADDR: return "FRAMEADDR";
|
case ISD::FRAMEADDR: return "FRAMEADDR";
|
||||||
|
case ISD::EXCEPTIONADDR: return "EXCEPTIONADDR";
|
||||||
|
case ISD::EHSELECTION: return "EHSELECTION";
|
||||||
case ISD::ConstantPool: return "ConstantPool";
|
case ISD::ConstantPool: return "ConstantPool";
|
||||||
case ISD::ExternalSymbol: return "ExternalSymbol";
|
case ISD::ExternalSymbol: return "ExternalSymbol";
|
||||||
case ISD::INTRINSIC_WO_CHAIN: {
|
case ISD::INTRINSIC_WO_CHAIN: {
|
||||||
|
@ -496,8 +496,8 @@ public:
|
|||||||
void visitJumpTable(SelectionDAGISel::JumpTable &JT);
|
void visitJumpTable(SelectionDAGISel::JumpTable &JT);
|
||||||
|
|
||||||
// These all get lowered before this pass.
|
// These all get lowered before this pass.
|
||||||
void visitInvoke(InvokeInst &I) { assert(0 && "TODO"); }
|
void visitInvoke(InvokeInst &I);
|
||||||
void visitUnwind(UnwindInst &I) { assert(0 && "TODO"); }
|
void visitUnwind(UnwindInst &I);
|
||||||
|
|
||||||
void visitScalarBinary(User &I, unsigned OpCode);
|
void visitScalarBinary(User &I, unsigned OpCode);
|
||||||
void visitVectorBinary(User &I, unsigned OpCode);
|
void visitVectorBinary(User &I, unsigned OpCode);
|
||||||
@ -1101,6 +1101,56 @@ void SelectionDAGLowering::visitJumpTable(SelectionDAGISel::JumpTable &JT) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SelectionDAGLowering::visitInvoke(InvokeInst &I) {
|
||||||
|
// Retrieve successors.
|
||||||
|
MachineBasicBlock *Return = FuncInfo.MBBMap[I.getSuccessor(0)];
|
||||||
|
MachineBasicBlock *LandingPad = FuncInfo.MBBMap[I.getSuccessor(1)];
|
||||||
|
|
||||||
|
// Mark landing pad so that it doesn't get deleted in branch folding.
|
||||||
|
LandingPad->setIsLandingPad();
|
||||||
|
|
||||||
|
// Insert a label before the invoke call to mark the try range.
|
||||||
|
// This can be used to detect deletion of the invoke via the
|
||||||
|
// MachineModuleInfo.
|
||||||
|
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
|
||||||
|
unsigned BeginLabel = MMI->NextLabelID();
|
||||||
|
DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
|
||||||
|
DAG.getConstant(BeginLabel, MVT::i32)));
|
||||||
|
|
||||||
|
// Insert a normal call instruction.
|
||||||
|
std::vector<Value*> Args;
|
||||||
|
for (InvokeInst::op_iterator OI = I.op_begin() + 3, E = I.op_end();
|
||||||
|
OI != E; ++OI) {
|
||||||
|
Args.push_back(*OI);
|
||||||
|
}
|
||||||
|
CallInst *NewCall = new CallInst(I.getCalledValue(), &Args[0], Args.size(),
|
||||||
|
I.getName(), &I);
|
||||||
|
NewCall->setCallingConv(I.getCallingConv());
|
||||||
|
I.replaceAllUsesWith(NewCall);
|
||||||
|
visitCall(*NewCall);
|
||||||
|
|
||||||
|
// Insert a label before the invoke call to mark the try range.
|
||||||
|
// This can be used to detect deletion of the invoke via the
|
||||||
|
// MachineModuleInfo.
|
||||||
|
unsigned EndLabel = MMI->NextLabelID();
|
||||||
|
DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
|
||||||
|
DAG.getConstant(EndLabel, MVT::i32)));
|
||||||
|
|
||||||
|
// Inform MachineModuleInfo of range.
|
||||||
|
MMI->addInvoke(LandingPad, BeginLabel, EndLabel);
|
||||||
|
|
||||||
|
// Drop into normal successor.
|
||||||
|
DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(),
|
||||||
|
DAG.getBasicBlock(Return)));
|
||||||
|
|
||||||
|
// Update successor info
|
||||||
|
CurMBB->addSuccessor(Return);
|
||||||
|
CurMBB->addSuccessor(LandingPad);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectionDAGLowering::visitUnwind(UnwindInst &I) {
|
||||||
|
}
|
||||||
|
|
||||||
void SelectionDAGLowering::visitSwitch(SwitchInst &I) {
|
void SelectionDAGLowering::visitSwitch(SwitchInst &I) {
|
||||||
// Figure out which block is immediately after the current one.
|
// Figure out which block is immediately after the current one.
|
||||||
MachineBasicBlock *NextBlock = 0;
|
MachineBasicBlock *NextBlock = 0;
|
||||||
@ -2033,6 +2083,91 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Intrinsic::eh_exception: {
|
||||||
|
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
|
||||||
|
|
||||||
|
// Add a label to mark the beginning of the landing pad. Deletion of the
|
||||||
|
// landing pad can thus be detected via the MachineModuleInfo.
|
||||||
|
unsigned LabelID = MMI->addLandingPad(CurMBB);
|
||||||
|
DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(),
|
||||||
|
DAG.getConstant(LabelID, MVT::i32)));
|
||||||
|
|
||||||
|
// Mark exception register as live in.
|
||||||
|
const MRegisterInfo *MRI = DAG.getTarget().getRegisterInfo();
|
||||||
|
unsigned Reg = MRI->getEHExceptionRegister();
|
||||||
|
if (Reg) CurMBB->addLiveIn(Reg);
|
||||||
|
|
||||||
|
// Insert the EXCEPTIONADDR instruction.
|
||||||
|
SDVTList VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other);
|
||||||
|
SDOperand Ops[1];
|
||||||
|
Ops[0] = DAG.getRoot();
|
||||||
|
SDOperand Op = DAG.getNode(ISD::EXCEPTIONADDR, VTs, Ops, 1);
|
||||||
|
setValue(&I, Op);
|
||||||
|
DAG.setRoot(Op.getValue(1));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Intrinsic::eh_handlers: {
|
||||||
|
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
|
||||||
|
|
||||||
|
// Inform the MachineModuleInfo of the personality for this landing pad.
|
||||||
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(2))) {
|
||||||
|
if (CE->getOpcode() == Instruction::BitCast) {
|
||||||
|
MMI->addPersonality(CurMBB,
|
||||||
|
cast<Function>(CE->getOperand(0)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gather all the type infos for this landing pad and pass them along to
|
||||||
|
// MachineModuleInfo.
|
||||||
|
std::vector<GlobalVariable *> TyInfo;
|
||||||
|
for (unsigned i = 3, N = I.getNumOperands(); i < N; ++i) {
|
||||||
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(i))) {
|
||||||
|
if (CE->getOpcode() == Instruction::BitCast) {
|
||||||
|
TyInfo.push_back(cast<GlobalVariable>(CE->getOperand(0)));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TyInfo.push_back(NULL);
|
||||||
|
}
|
||||||
|
MMI->addCatchTypeInfo(CurMBB, TyInfo);
|
||||||
|
|
||||||
|
// Mark exception selector register as live in.
|
||||||
|
const MRegisterInfo *MRI = DAG.getTarget().getRegisterInfo();
|
||||||
|
unsigned Reg = MRI->getEHHandlerRegister();
|
||||||
|
if (Reg) CurMBB->addLiveIn(Reg);
|
||||||
|
|
||||||
|
// Insert the EHSELECTION instruction.
|
||||||
|
SDVTList VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other);
|
||||||
|
SDOperand Ops[2];
|
||||||
|
Ops[0] = getValue(I.getOperand(1));
|
||||||
|
Ops[1] = getRoot();
|
||||||
|
SDOperand Op = DAG.getNode(ISD::EHSELECTION, VTs, Ops, 2);
|
||||||
|
setValue(&I, Op);
|
||||||
|
DAG.setRoot(Op.getValue(1));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Intrinsic::eh_typeid_for: {
|
||||||
|
GlobalVariable *GV = NULL;
|
||||||
|
|
||||||
|
// Find the type id for the given typeinfo.
|
||||||
|
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
|
||||||
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(1))) {
|
||||||
|
if (CE->getOpcode() == Instruction::BitCast) {
|
||||||
|
GV = cast<GlobalVariable>(CE->getOperand(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned TypeID = MMI->getTypeIDFor(GV);
|
||||||
|
setValue(&I, DAG.getConstant(TypeID, MVT::i32));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
case Intrinsic::sqrt_f32:
|
case Intrinsic::sqrt_f32:
|
||||||
case Intrinsic::sqrt_f64:
|
case Intrinsic::sqrt_f64:
|
||||||
setValue(&I, DAG.getNode(ISD::FSQRT,
|
setValue(&I, DAG.getNode(ISD::FSQRT,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user