+/// FindAllCleanupSelectors - Find all eh.selector calls that are clean-ups.
+void DwarfEHPrepare::
+FindAllCleanupSelectors(SmallPtrSet<IntrinsicInst*, 32> &Sels) {
+ for (Value::use_iterator
+ I = SelectorIntrinsic->use_begin(),
+ E = SelectorIntrinsic->use_end(); I != E; ++I) {
+ IntrinsicInst *SI = cast<IntrinsicInst>(I);
+ if (!SI || SI->getParent()->getParent() != F) continue;
+
+ unsigned NumOps = SI->getNumOperands();
+ if (NumOps > 4) continue;
+ bool IsCleanUp = (NumOps == 3);
+
+ if (!IsCleanUp)
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(SI->getOperand(3)))
+ IsCleanUp = (CI->getZExtValue() == 0);
+
+ if (IsCleanUp)
+ Sels.insert(SI);
+ }
+}
+
+/// FindAllURoRInvokes - Find all URoR invokes in the function.
+void DwarfEHPrepare::
+FindAllURoRInvokes(SmallPtrSet<InvokeInst*, 32> &URoRInvokes) {
+ for (Value::use_iterator
+ I = URoR->use_begin(),
+ E = URoR->use_end(); I != E; ++I) {
+ if (InvokeInst *II = dyn_cast<InvokeInst>(I))
+ URoRInvokes.insert(II);
+ }
+}
+
+/// CleanupSelectors - Any remaining eh.selector intrinsic calls which still use
+/// the ".llvm.eh.catch.all.value" call need to convert to using its
+/// initializer instead.
+bool DwarfEHPrepare::CleanupSelectors() {
+ if (!EHCatchAllValue) return false;
+
+ if (!SelectorIntrinsic) {
+ SelectorIntrinsic =
+ Intrinsic::getDeclaration(F->getParent(), Intrinsic::eh_selector);
+ if (!SelectorIntrinsic) return false;
+ }
+
+ bool Changed = false;
+ for (Value::use_iterator
+ I = SelectorIntrinsic->use_begin(),
+ E = SelectorIntrinsic->use_end(); I != E; ++I) {
+ IntrinsicInst *Sel = dyn_cast<IntrinsicInst>(I);
+ if (!Sel || Sel->getParent()->getParent() != F) continue;
+
+ // Index of the ".llvm.eh.catch.all.value" variable.
+ unsigned OpIdx = Sel->getNumOperands() - 1;
+ GlobalVariable *GV = dyn_cast<GlobalVariable>(Sel->getOperand(OpIdx));
+ if (GV != EHCatchAllValue) continue;
+ Sel->setOperand(OpIdx, EHCatchAllValue->getInitializer());
+ Changed = true;
+ }
+
+ return Changed;
+}
+