, RootScope(NULL)
, FrameMoves()
, LandingPads()
-{}
+, Personalities()
+, CallsEHReturn(0)
+, CallsUnwindInit(0)
+{
+ // Always emit "no personality" info
+ Personalities.push_back(NULL);
+}
MachineModuleInfo::~MachineModuleInfo() {
}
// Clean up exception info.
LandingPads.clear();
TypeInfos.clear();
+ FilterIds.clear();
+ FilterEnds.clear();
+ CallsEHReturn = 0;
+ CallsUnwindInit = 0;
}
/// getDescFor - Convert a Value to a debug information descriptor.
Function *Personality) {
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
LP.Personality = Personality;
+
+ for (unsigned i = 0; i < Personalities.size(); ++i)
+ if (Personalities[i] == Personality)
+ return;
+
+ Personalities.push_back(Personality);
}
/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
for (unsigned N = TyInfo.size(); N; --N)
LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
}
-
-/// setIsFilterLandingPad - Indicates that the landing pad is a throw filter.
+
+/// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
///
-void MachineModuleInfo::setIsFilterLandingPad(MachineBasicBlock *LandingPad) {
+void MachineModuleInfo::addFilterTypeInfo(MachineBasicBlock *LandingPad,
+ std::vector<GlobalVariable *> &TyInfo) {
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
- LP.IsFilter = true;
+ std::vector<unsigned> IdsInFilter (TyInfo.size());
+ for (unsigned I = 0, E = TyInfo.size(); I != E; ++I)
+ IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
+ LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
+}
+
+/// addCleanup - Add a cleanup action for a landing pad.
+///
+void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
+ LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
+ LP.TypeIds.push_back(0);
}
/// TidyLandingPads - Remap landing pad labels and remove any deleted landing
LandingPadInfo &LandingPad = LandingPads[i];
LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel);
- if (!LandingPad.LandingPadLabel) {
+ // Special case: we *should* emit LPs with null LP MBB. This indicates
+ // "rethrow" case.
+ if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
LandingPads.erase(LandingPads.begin() + i);
continue;
}
-
+
for (unsigned j=0; j != LandingPads[i].BeginLabels.size(); ) {
unsigned BeginLabel = MappedLabel(LandingPad.BeginLabels[j]);
unsigned EndLabel = MappedLabel(LandingPad.EndLabels[j]);
-
-
+
+
if (!BeginLabel || !EndLabel) {
LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
LandingPad.EndLabels[j] = EndLabel;
++j;
}
-
+
+ // Remove landing pads with no try-ranges.
+ if (!LandingPads[i].BeginLabels.size()) {
+ LandingPads.erase(LandingPads.begin() + i);
+ continue;
+ }
+
+ // If there is no landing pad, ensure that the list of typeids is empty.
+ // If the only typeid is a cleanup, this is the same as having no typeids.
+ if (!LandingPad.LandingPadBlock ||
+ (LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0]))
+ LandingPad.TypeIds.clear();
+
++i;
}
}
return TypeInfos.size();
}
-/// getLandingPadInfos - Return a reference to the landing pad info for the
-/// current function.
+/// getFilterIDFor - Return the filter id for the specified typeinfos. This is
+/// function wide.
+int MachineModuleInfo::getFilterIDFor(std::vector<unsigned> &TyIds) {
+ // If the new filter coincides with the tail of an existing filter, then
+ // re-use the existing filter. Folding filters more than this requires
+ // re-ordering filters and/or their elements - probably not worth it.
+ for (std::vector<unsigned>::iterator I = FilterEnds.begin(),
+ E = FilterEnds.end(); I != E; ++I) {
+ unsigned i = *I, j = TyIds.size();
+
+ while (i && j)
+ if (FilterIds[--i] != TyIds[--j])
+ goto try_next;
+
+ if (!j)
+ // The new filter coincides with range [i, end) of the existing filter.
+ return -(1 + i);
+
+try_next:;
+ }
+
+ // Add the new filter.
+ int FilterID = -(1 + FilterIds.size());
+ FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
+ for (unsigned I = 0, N = TyIds.size(); I != N; ++I)
+ FilterIds.push_back(TyIds[I]);
+ FilterEnds.push_back(FilterIds.size());
+ FilterIds.push_back(0); // terminator
+ return FilterID;
+}
+
+/// getPersonality - Return the personality function for the current function.
Function *MachineModuleInfo::getPersonality() const {
+ // FIXME: Until PR1414 will be fixed, we're using 1 personality function per
+ // function
return !LandingPads.empty() ? LandingPads[0].Personality : NULL;
}
+/// getPersonalityIndex - Return unique index for current personality
+/// function. NULL personality function should always get zero index.
+unsigned MachineModuleInfo::getPersonalityIndex() const {
+ const Function* Personality = NULL;
+
+ // Scan landing pads. If there is at least one non-NULL personality - use it.
+ for (unsigned i = 0; i != LandingPads.size(); ++i)
+ if (LandingPads[i].Personality) {
+ Personality = LandingPads[i].Personality;
+ break;
+ }
+
+ for (unsigned i = 0; i < Personalities.size(); ++i) {
+ if (Personalities[i] == Personality)
+ return i;
+ }
+
+ // This should never happen
+ assert(0 && "Personality function should be set!");
+ return 0;
+}
//===----------------------------------------------------------------------===//
/// DebugLabelFolding pass - This pass prunes out redundant labels. This allows