/// anywhere in the function.
std::map<const AllocaInst*, int> StaticAllocaMap;
+#ifndef NDEBUG
+ SmallSet<Instruction*, 8> CatchInfoLost;
+ SmallSet<Instruction*, 8> CatchInfoFound;
+#endif
+
unsigned MakeReg(MVT::ValueType VT) {
return RegMap->createVirtualRegister(TLI.getRegClassFor(VT));
}
};
}
+/// isFilterOrSelector - Return true if this instruction is a call to the
+/// eh.filter or the eh.selector intrinsic.
+static bool isFilterOrSelector(Instruction *I) {
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
+ return II->getIntrinsicID() == Intrinsic::eh_selector
+ || II->getIntrinsicID() == Intrinsic::eh_filter;
+ return false;
+}
+
/// isUsedOutsideOfDefiningBlock - Return true if this instruction is used by
/// PHI nodes or outside of the basic block that defines it, or used by a
/// switch instruction, which may expand to multiple basic blocks.
if (PN->use_empty()) continue;
MVT::ValueType VT = TLI.getValueType(PN->getType());
- unsigned NumElements;
+ unsigned NumRegisters;
if (VT != MVT::Vector)
- NumElements = TLI.getNumElements(VT);
+ NumRegisters = TLI.getNumRegisters(VT);
else {
MVT::ValueType VT1,VT2;
- NumElements =
+ NumRegisters =
TLI.getVectorTypeBreakdown(cast<VectorType>(PN->getType()),
VT1, VT2);
}
unsigned PHIReg = ValueMap[PN];
assert(PHIReg && "PHI node does not have an assigned virtual register!");
const TargetInstrInfo *TII = TLI.getTargetMachine().getInstrInfo();
- for (unsigned i = 0; i != NumElements; ++i)
+ for (unsigned i = 0; i != NumRegisters; ++i)
BuildMI(MBB, TII->get(TargetInstrInfo::PHI), PHIReg+i);
}
}
// The common case is that we will only create one register for this
// value. If we have that case, create and return the virtual register.
- unsigned NV = TLI.getNumElements(VT);
+ unsigned NV = TLI.getNumRegisters(VT);
if (NV == 1) {
// If we are promoting this value, pick the next largest supported type.
MVT::ValueType PromotedType = TLI.getTypeToTransformTo(VT);
// Source must be expanded. This input value is actually coming from the
// register pair InReg and InReg+1.
MVT::ValueType DestVT = TLI.getTypeToExpandTo(VT);
- unsigned NumVals = TLI.getNumElements(VT);
+ unsigned NumVals = TLI.getNumRegisters(VT);
N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT);
if (NumVals == 1)
N = DAG.getNode(ISD::BIT_CONVERT, VT, N);
if (MVT::isVector(PTyElementVT)) {
Ops.push_back(DAG.getConstant(NE * MVT::getVectorNumElements(PTyElementVT), MVT::i32));
- Ops.push_back(DAG.getValueType(MVT::getVectorBaseType(PTyElementVT)));
+ Ops.push_back(DAG.getValueType(MVT::getVectorElementType(PTyElementVT)));
N = DAG.getNode(ISD::VCONCAT_VECTORS, MVT::Vector, &Ops[0], Ops.size());
} else {
Ops.push_back(DAG.getConstant(NE, MVT::i32));
return NULL;
}
+/// addCatchInfo - Extract the personality and type infos from an eh.selector
+/// or eh.filter call, and add them to the specified machine basic block.
+static void addCatchInfo(CallInst &I, MachineModuleInfo *MMI,
+ MachineBasicBlock *MBB) {
+ // Inform the MachineModuleInfo of the personality for this landing pad.
+ ConstantExpr *CE = cast<ConstantExpr>(I.getOperand(2));
+ assert(CE->getOpcode() == Instruction::BitCast &&
+ isa<Function>(CE->getOperand(0)) &&
+ "Personality should be a function");
+ MMI->addPersonality(MBB, 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) {
+ Constant *C = cast<Constant>(I.getOperand(i));
+ GlobalVariable *GV = ExtractGlobalVariable(C);
+ assert (GV || isa<ConstantPointerNull>(C) &&
+ "TypeInfo must be a global variable or NULL");
+ TyInfo.push_back(GV);
+ }
+ if (I.getCalledFunction()->getIntrinsicID() == Intrinsic::eh_filter)
+ MMI->addFilterTypeInfo(MBB, TyInfo);
+ else
+ MMI->addCatchTypeInfo(MBB, TyInfo);
+}
+
/// visitIntrinsicCall - Lower the call to the specified intrinsic function. If
/// we want to emit this as a call to a named external function, return the name
/// otherwise lower it and return null.
case Intrinsic::eh_exception: {
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
- if (MMI) {
+ if (ExceptionHandling && MMI) {
// Mark exception register as live in.
unsigned Reg = TLI.getExceptionAddressRegister();
if (Reg) CurMBB->addLiveIn(Reg);
case Intrinsic::eh_selector:
case Intrinsic::eh_filter:{
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
-
- if (MMI) {
- // Inform the MachineModuleInfo of the personality for this landing pad.
- ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(2));
- assert(CE && CE->getOpcode() == Instruction::BitCast &&
- isa<Function>(CE->getOperand(0)) &&
- "Personality should be a function");
- 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) {
- Constant *C = cast<Constant>(I.getOperand(i));
- GlobalVariable *GV = ExtractGlobalVariable(C);
- assert (GV || isa<ConstantPointerNull>(C) &&
- "TypeInfo must be a global variable or NULL");
- TyInfo.push_back(GV);
- }
- if (Intrinsic == Intrinsic::eh_filter)
- MMI->addFilterTypeInfo(CurMBB, TyInfo);
+
+ if (ExceptionHandling && MMI) {
+ if (CurMBB->isLandingPad())
+ addCatchInfo(I, MMI, CurMBB);
+#ifndef NDEBUG
else
- MMI->addCatchTypeInfo(CurMBB, TyInfo);
+ FuncInfo.CatchInfoLost.insert(&I);
+#endif
// Mark exception selector register as live in.
unsigned Reg = TLI.getExceptionSelectorRegister();
case Intrinsic::prefetch:
// FIXME: Currently discarding prefetches.
return 0;
+
+ case Intrinsic::var_annotation:
+ // Discard annotate attributes
+ return 0;
}
}
return DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, Val,
DAG.getConstant(MVT::getVectorNumElements(RegVT),
MVT::i32),
- DAG.getValueType(MVT::getVectorBaseType(RegVT)));
+ DAG.getValueType(MVT::getVectorElementType(RegVT)));
}
if (MVT::isInteger(RegVT)) {
unsigned NumRegs = 1;
if (OpInfo.ConstraintVT != MVT::Other)
- NumRegs = TLI.getNumElements(OpInfo.ConstraintVT);
+ NumRegs = TLI.getNumRegisters(OpInfo.ConstraintVT);
MVT::ValueType RegVT;
MVT::ValueType ValueVT = OpInfo.ConstraintVT;
// Otherwise, if this was a reference to an LLVM register class, create vregs
// for this reference.
std::vector<unsigned> RegClassRegs;
- if (PhysReg.second) {
+ const TargetRegisterClass *RC = PhysReg.second;
+ if (RC) {
// If this is an early clobber or tied register, our regalloc doesn't know
// how to maintain the constraint. If it isn't, go ahead and create vreg
// and let the regalloc do the right thing.
// Check to see if this register is allocatable (i.e. don't give out the
// stack pointer).
- const TargetRegisterClass *RC = isAllocatableRegister(Reg, MF, TLI, MRI);
- if (!RC) {
- // Make sure we find consecutive registers.
- NumAllocated = 0;
- continue;
+ if (RC == 0) {
+ RC = isAllocatableRegister(Reg, MF, TLI, MRI);
+ if (!RC) { // Couldn't allocate this register.
+ // Reset NumAllocated to make sure we return consecutive registers.
+ NumAllocated = 0;
+ continue;
+ }
}
// Okay, this register is good, we can use it.
// integers. Figure out what the destination type is and how many small
// integers it turns into.
MVT::ValueType NVT = getTypeToExpandTo(VT);
- unsigned NumVals = getNumElements(VT);
+ unsigned NumVals = getNumRegisters(VT);
for (unsigned i = 0; i != NumVals; ++i) {
RetVals.push_back(NVT);
// if it isn't first piece, alignment must be 1
// integers. Figure out what the source elt type is and how many small
// integers it is.
MVT::ValueType NVT = getTypeToExpandTo(VT);
- unsigned NumVals = getNumElements(VT);
+ unsigned NumVals = getNumRegisters(VT);
for (unsigned i = 0; i != NumVals; ++i)
RetTys.push_back(NVT);
} else {
FunctionLoweringInfo FuncInfo(TLI, Fn, MF);
- for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
- if (InvokeInst *Invoke = dyn_cast<InvokeInst>(I->getTerminator())) {
- // Mark landing pad.
- MachineBasicBlock *LandingPad = FuncInfo.MBBMap[Invoke->getSuccessor(1)];
- LandingPad->setIsLandingPad();
- }
+ if (ExceptionHandling)
+ for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
+ if (InvokeInst *Invoke = dyn_cast<InvokeInst>(I->getTerminator()))
+ // Mark landing pad.
+ FuncInfo.MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
SelectBasicBlock(I, MF, FuncInfo);
E = MF.livein_end(); I != E; ++I)
BB->addLiveIn(I->first);
+#ifndef NDEBUG
+ assert(FuncInfo.CatchInfoFound.size() == FuncInfo.CatchInfoLost.size() &&
+ "Not all catch info was assigned to a landing pad!");
+#endif
+
return true;
}
return DAG.getCopyToReg(getRoot(), Reg, Op);
} else {
DestVT = TLI.getTypeToExpandTo(SrcVT);
- unsigned NumVals = TLI.getNumElements(SrcVT);
+ unsigned NumVals = TLI.getNumRegisters(SrcVT);
if (NumVals == 1)
return DAG.getCopyToReg(getRoot(), Reg,
DAG.getNode(ISD::BIT_CONVERT, DestVT, Op));
EmitFunctionEntryCode(F, SDL.DAG.getMachineFunction());
}
+static void copyCatchInfo(BasicBlock *SrcBB, BasicBlock *DestBB,
+ MachineModuleInfo *MMI, FunctionLoweringInfo &FLI) {
+ assert(!FLI.MBBMap[SrcBB]->isLandingPad() &&
+ "Copying catch info out of a landing pad!");
+ for (BasicBlock::iterator I = SrcBB->begin(), E = --SrcBB->end(); I != E; ++I)
+ if (isFilterOrSelector(I)) {
+ // Apply the catch info to DestBB.
+ addCatchInfo(cast<CallInst>(*I), MMI, FLI.MBBMap[DestBB]);
+#ifndef NDEBUG
+ FLI.CatchInfoFound.insert(I);
+#endif
+ }
+}
+
void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate,
FunctionLoweringInfo &FuncInfo) {
BB = FuncInfo.MBBMap[LLVMBB];
SDL.setCurrentBasicBlock(BB);
- if (ExceptionHandling && BB->isLandingPad()) {
- MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
- if (MMI) {
- // 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(BB);
- DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(),
- DAG.getConstant(LabelID, MVT::i32)));
+ if (ExceptionHandling && MMI && BB->isLandingPad()) {
+ // 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(BB);
+ DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(),
+ DAG.getConstant(LabelID, MVT::i32)));
+
+ // FIXME: Hack around an exception handling flaw (PR1508): the personality
+ // function and list of typeids logically belong to the invoke (or, if you
+ // like, the basic block containing the invoke), and need to be associated
+ // with it in the dwarf exception handling tables. Currently however the
+ // information is provided by intrinsics (eh.filter and eh.selector) that
+ // can be moved to unexpected places by the optimizers: if the unwind edge
+ // is critical, then breaking it can result in the intrinsics being in the
+ // successor of the landing pad, not the landing pad itself. This results
+ // in exceptions not being caught because no typeids are associated with
+ // the invoke. This may not be the only way things can go wrong, but it
+ // is the only way we try to work around for the moment.
+ BranchInst *Br = dyn_cast<BranchInst>(LLVMBB->getTerminator());
+
+ if (Br && Br->isUnconditional()) { // Critical edge?
+ BasicBlock::iterator I, E;
+ for (I = LLVMBB->begin(), E = --LLVMBB->end(); I != E; ++I)
+ if (isFilterOrSelector(I))
+ break;
+
+ if (I == E)
+ // No catch info found - try to extract some from the successor.
+ copyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, FuncInfo);
}
}
// Remember that this register needs to added to the machine PHI node as
// the input for this MBB.
MVT::ValueType VT = TLI.getValueType(PN->getType());
- unsigned NumElements;
+ unsigned NumRegisters;
if (VT != MVT::Vector)
- NumElements = TLI.getNumElements(VT);
+ NumRegisters = TLI.getNumRegisters(VT);
else {
MVT::ValueType VT1,VT2;
- NumElements =
+ NumRegisters =
TLI.getVectorTypeBreakdown(cast<VectorType>(PN->getType()),
VT1, VT2);
}
- for (unsigned i = 0, e = NumElements; i != e; ++i)
+ for (unsigned i = 0, e = NumRegisters; i != e; ++i)
PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg+i));
}
}