SmallVector<unsigned, 1> EndLabels; // Labels after invoke.
unsigned LandingPadLabel; // Label at beginning of landing pad.
Function *Personality; // Personality function.
- std::vector<unsigned> TypeIds; // List of type ids.
- bool IsFilter; // Indicate if the landing pad is a
- // throw filter.
-
+ std::vector<int> TypeIds; // List of type ids (filters negative)
+
LandingPadInfo(MachineBasicBlock *MBB)
: LandingPadBlock(MBB)
, LandingPadLabel(0)
, Personality(NULL)
, TypeIds()
- , IsFilter(false)
{}
};
//
std::vector<GlobalVariable *> TypeInfos;
+ // FilterIds - List of typeids encoding filters used in the current function.
+ //
+ std::vector<unsigned> FilterIds;
+
// Personalities - Vector of all personality functions ever seen. Used to emit
// common EH frames.
std::vector<Function *> Personalities;
const std::vector<Function *>& getPersonalities() const {
return Personalities;
}
-
+
/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
///
void addCatchTypeInfo(MachineBasicBlock *LandingPad,
std::vector<GlobalVariable *> &TyInfo);
-
- /// setIsFilterLandingPad - Indicates that the landing pad is a throw filter.
+
+ /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
///
- void setIsFilterLandingPad(MachineBasicBlock *LandingPad);
-
+ void addFilterTypeInfo(MachineBasicBlock *LandingPad,
+ std::vector<GlobalVariable *> &TyInfo);
+
/// getTypeIDFor - Return the type id for the specified typeinfo. This is
/// function wide.
unsigned getTypeIDFor(GlobalVariable *TI);
-
+
+ /// getFilterIDFor - Return the id of the filter encoded by TyIds. This is
+ /// function wide.
+ int getFilterIDFor(std::vector<unsigned> &TyIds);
+
/// TidyLandingPads - Remap landing pad labels and remove any deleted landing
/// pads.
void TidyLandingPads();
const std::vector<GlobalVariable *> &getTypeInfos() const {
return TypeInfos;
}
-
+
+ /// getFilterIds - Return a reference to the typeids encoding filters used in
+ /// the current function.
+ const std::vector<unsigned> &getFilterIds() const {
+ return FilterIds;
+ }
+
/// getPersonality - Return a personality function if available. The presence
/// of one is required to emit exception handling info.
Function *getPersonality() const;
/// EquivPads - Whether two landing pads have equivalent actions.
static bool EquivPads(const LandingPadInfo *L, const LandingPadInfo *R) {
- const std::vector<unsigned> &LIds = L->TypeIds;
- const std::vector<unsigned> &RIds = R->TypeIds;
+ const std::vector<int> &LIds = L->TypeIds;
+ const std::vector<int> &RIds = R->TypeIds;
unsigned LSize = LIds.size(), RSize = RIds.size();
- if (L->IsFilter != R->IsFilter)
- return false;
-
if (LSize != RSize)
return false;
/// PadLT - An order on landing pads, with EquivPads as order equivalence.
static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
- const std::vector<unsigned> &LIds = L->TypeIds;
- const std::vector<unsigned> &RIds = R->TypeIds;
+ const std::vector<int> &LIds = L->TypeIds;
+ const std::vector<int> &RIds = R->TypeIds;
unsigned LSize = LIds.size(), RSize = RIds.size();
- if (L->IsFilter != R->IsFilter)
- // Make filters come last
- return L->IsFilter < R->IsFilter;
-
if (LSize != RSize)
return LSize < RSize;
MMI->TidyLandingPads();
const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
+ const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
if (PadInfos.empty()) return;
// Gather first action index for each landing pad site.
SmallVector<unsigned, 32> Actions;
- // FIXME - Assume there is only one filter typeinfo list per function
- // time being. I.E., Each call to eh_filter will have the same list.
- // This can change if a function is inlined.
- const LandingPadInfo *Filter = 0;
-
// Compute sizes for exception table.
unsigned SizeSites = 0;
unsigned SizeActions = 0;
unsigned SizeSiteActions = 0;
if (!i || !EquivPads(LandingPad, LandingPads[i-1])) {
- const std::vector<unsigned> &TypeIds = LandingPad->TypeIds;
+ const std::vector<int> &TypeIds = LandingPad->TypeIds;
unsigned SizeAction = 0;
- if (LandingPad->IsFilter) {
- // FIXME - Assume there is only one filter typeinfo list per function
- // time being. I.E., Each call to eh_filter will have the same list.
- // This can change if a function is inlined.
- Filter = LandingPad;
- SizeAction = Asm->SizeSLEB128(-1) + Asm->SizeSLEB128(0);
- SizeSiteActions += SizeAction;
- // Record the first action of the landing pad site.
- FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
- } else if (TypeIds.empty()) {
+ if (TypeIds.empty()) {
FirstAction = 0;
} else {
// Gather the action sizes
for (unsigned j = 0, M = TypeIds.size(); j != M; ++j) {
- unsigned TypeID = TypeIds[j];
+ int TypeID = TypeIds[j];
unsigned SizeTypeID = Asm->SizeSLEB128(TypeID);
signed Action = j ? -(SizeAction + SizeTypeID) : 0;
SizeAction = SizeTypeID + Asm->SizeSLEB128(Action);
for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
if (!i || Actions[i] != Actions[i-1]) {
const LandingPadInfo *LandingPad = LandingPads[i];
- const std::vector<unsigned> &TypeIds = LandingPad->TypeIds;
+ const std::vector<int> &TypeIds = LandingPad->TypeIds;
unsigned SizeAction = 0;
- if (LandingPad->IsFilter) {
- Asm->EmitSLEB128Bytes(-1);
+ for (unsigned j = 0, M = TypeIds.size(); j < M; ++j) {
+ int TypeID = TypeIds[j];
+ unsigned SizeTypeID = Asm->SizeSLEB128(TypeID);
+ Asm->EmitSLEB128Bytes(TypeID);
Asm->EOL("TypeInfo index");
- Asm->EmitSLEB128Bytes(0);
+ signed Action = j ? -(SizeAction + SizeTypeID) : 0;
+ SizeAction = SizeTypeID + Asm->SizeSLEB128(Action);
+ Asm->EmitSLEB128Bytes(Action);
Asm->EOL("Next action");
- } else {
- for (unsigned j = 0, M = TypeIds.size(); j < M; ++j) {
- unsigned TypeID = TypeIds[j];
- unsigned SizeTypeID = Asm->SizeSLEB128(TypeID);
- Asm->EmitSLEB128Bytes(TypeID);
- Asm->EOL("TypeInfo index");
- signed Action = j ? -(SizeAction + SizeTypeID) : 0;
- SizeAction = SizeTypeID + Asm->SizeSLEB128(Action);
- Asm->EmitSLEB128Bytes(Action);
- Asm->EOL("Next action");
- }
}
}
}
Asm->EOL("TypeInfo");
}
- // Emit the filter typeinfo.
- if (Filter) {
- const std::vector<unsigned> &TypeIds = Filter->TypeIds;
- for (unsigned j = 0, M = TypeIds.size(); j < M; ++j) {
- unsigned TypeID = TypeIds[j];
- Asm->EmitSLEB128Bytes(TypeID);
- Asm->EOL("TypeInfo index");
- }
- Asm->EmitSLEB128Bytes(0);
- Asm->EOL("End of filter typeinfo");
+ // Emit the filter typeids.
+ for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
+ unsigned TypeID = FilterIds[j];
+ Asm->EmitSLEB128Bytes(TypeID);
+ Asm->EOL("Filter TypeInfo index");
}
Asm->EmitAlignment(2);
// Clean up exception info.
LandingPads.clear();
TypeInfos.clear();
+ FilterIds.clear();
}
/// getDescFor - Convert a Value to a debug information descriptor.
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));
}
/// TidyLandingPads - Remap landing pad labels and remove any deleted landing
return TypeInfos.size();
}
+/// getFilterIDFor - Return the filter id for the specified typeinfos. This is
+/// function wide.
+int MachineModuleInfo::getFilterIDFor(std::vector<unsigned> &TyIds) {
+ // TODO: map duplicate filters to the same filter id; a filter equal to the
+ // tail of an existing filter also need not be added; re-order filters and
+ // filter elements to maximize this kind of sharing.
+ 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]);
+ 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