Only emit one entry in the exception action table for each action, even if

it occurs for multiple landing pads.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37267 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan Sands 2007-05-21 18:50:28 +00:00
parent 126f17a176
commit 7bf7a446a5

View File

@ -2894,6 +2894,45 @@ private:
O << UsedDirective << EHFrameInfo.FnName << ".eh\n\n"; O << UsedDirective << EHFrameInfo.FnName << ".eh\n\n";
} }
/// 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;
unsigned LSize = LIds.size(), RSize = RIds.size();
if (L->IsFilter != R->IsFilter)
return false;
if (LSize != RSize)
return false;
for (unsigned i = 0; i != LSize; ++i)
if (LIds[i] != RIds[i])
return false;
return true;
}
/// 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;
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;
for (unsigned i = 0; i != LSize; ++i)
if (LIds[i] != RIds[i])
return LIds[i] < RIds[i];
return false; // Equivalent
}
/// EmitExceptionTable - Emit landpads and actions. /// EmitExceptionTable - Emit landpads and actions.
/// ///
/// The general organization of the table is complex, but the basic concepts /// The general organization of the table is complex, but the basic concepts
@ -2933,13 +2972,18 @@ private:
MMI->TidyLandingPads(); MMI->TidyLandingPads();
const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
const std::vector<LandingPadInfo> &LandingPads = MMI->getLandingPads(); const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
if (LandingPads.empty()) return; if (PadInfos.empty()) return;
// FIXME - Should fold actions for multiple landing pads. // Sort the landing pads in order of their type ids. This is used to fold
// duplicate actions.
SmallVector<const LandingPadInfo *, 32> LandingPads(PadInfos.size(), NULL);
for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
LandingPads[i] = &PadInfos[i];
std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
// Gather first action index for each landing pad site. // Gather first action index for each landing pad site.
SmallVector<unsigned, 8> Actions; SmallVector<unsigned, 32> Actions;
// FIXME - Assume there is only one filter typeinfo list per function // 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. // time being. I.E., Each call to eh_filter will have the same list.
@ -2952,19 +2996,21 @@ private:
// Look at each landing pad site to compute size. We need the size of each // Look at each landing pad site to compute size. We need the size of each
// landing pad site info and the size of the landing pad's actions. // landing pad site info and the size of the landing pad's actions.
for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
const LandingPadInfo &LandingPad = LandingPads[i];
bool IsFilter = LandingPad.IsFilter;
unsigned SizeSiteActions = 0;
const std::vector<unsigned> &TypeIds = LandingPad.TypeIds;
unsigned SizeAction = 0;
signed FirstAction; signed FirstAction;
if (IsFilter) { for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
const LandingPadInfo *LandingPad = LandingPads[i];
unsigned SizeSiteActions = 0;
if (!i || !EquivPads(LandingPad, LandingPads[i-1])) {
const std::vector<unsigned> &TypeIds = LandingPad->TypeIds;
unsigned SizeAction = 0;
if (LandingPad->IsFilter) {
// FIXME - Assume there is only one filter typeinfo list per function // 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. // time being. I.E., Each call to eh_filter will have the same list.
// This can change if a function is inlined. // This can change if a function is inlined.
Filter = &LandingPad; Filter = LandingPad;
SizeAction = Asm->SizeSLEB128(-1) + Asm->SizeSLEB128(0); SizeAction = Asm->SizeSLEB128(-1) + Asm->SizeSLEB128(0);
SizeSiteActions += SizeAction; SizeSiteActions += SizeAction;
// Record the first action of the landing pad site. // Record the first action of the landing pad site.
@ -2984,11 +3030,13 @@ private:
// Record the first action of the landing pad site. // Record the first action of the landing pad site.
FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
} }
} // else re-use previous FirstAction
Actions.push_back(FirstAction); Actions.push_back(FirstAction);
// Compute this sites contribution to size. // Compute this sites contribution to size.
SizeActions += SizeSiteActions; SizeActions += SizeSiteActions;
unsigned M = LandingPad.BeginLabels.size(); unsigned M = LandingPad->BeginLabels.size();
SizeSites += M*(sizeof(int32_t) + // Site start. SizeSites += M*(sizeof(int32_t) + // Site start.
sizeof(int32_t) + // Site length. sizeof(int32_t) + // Site length.
sizeof(int32_t) + // Landing pad. sizeof(int32_t) + // Landing pad.
@ -3035,9 +3083,9 @@ private:
PadMapType PadMap; PadMapType PadMap;
for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
const LandingPadInfo &LandingPad = LandingPads[i]; const LandingPadInfo *LandingPad = LandingPads[i];
for (unsigned j=0, E = LandingPad.BeginLabels.size(); j != E; ++j) { for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
unsigned BeginLabel = LandingPad.BeginLabels[j]; unsigned BeginLabel = LandingPad->BeginLabels[j];
assert(!PadMap.count(BeginLabel) && "duplicate landing pad labels!"); assert(!PadMap.count(BeginLabel) && "duplicate landing pad labels!");
PadSite P = { i, j }; PadSite P = { i, j };
PadMap[BeginLabel] = P; PadMap[BeginLabel] = P;
@ -3058,27 +3106,28 @@ private:
continue; continue;
PadSite P = L->second; PadSite P = L->second;
const LandingPadInfo &LandingPad = LandingPads[P.PadIndex]; const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
assert(BeginLabel == LandingPad.BeginLabels[P.SiteIndex] && assert(BeginLabel == LandingPad->BeginLabels[P.SiteIndex] &&
"Inconsistent landing pad map!"); "Inconsistent landing pad map!");
EmitSectionOffset("label", "eh_func_begin", BeginLabel, SubprogramCount, EmitSectionOffset("label", "eh_func_begin", BeginLabel, SubprogramCount,
false, true); false, true);
Asm->EOL("Region start"); Asm->EOL("Region start");
EmitDifference("label", LandingPad.EndLabels[P.SiteIndex], EmitDifference("label", LandingPad->EndLabels[P.SiteIndex],
"label", BeginLabel); "label", BeginLabel);
Asm->EOL("Region length"); Asm->EOL("Region length");
if (LandingPad.TypeIds.empty()) { if (LandingPad->TypeIds.empty()) {
if (TAI->getAddressSize() == sizeof(int32_t)) if (TAI->getAddressSize() == sizeof(int32_t))
Asm->EmitInt32(0); Asm->EmitInt32(0);
else else
Asm->EmitInt64(0); Asm->EmitInt64(0);
} else { } else {
EmitSectionOffset("label", "eh_func_begin", LandingPad.LandingPadLabel, EmitSectionOffset("label", "eh_func_begin",
SubprogramCount, false, true); LandingPad->LandingPadLabel, SubprogramCount,
false, true);
} }
Asm->EOL("Landing pad"); Asm->EOL("Landing pad");
@ -3089,11 +3138,12 @@ private:
// Emit the actions. // Emit the actions.
for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
const LandingPadInfo &LandingPad = LandingPads[i]; if (!i || Actions[i] != Actions[i-1]) {
const std::vector<unsigned> &TypeIds = LandingPad.TypeIds; const LandingPadInfo *LandingPad = LandingPads[i];
const std::vector<unsigned> &TypeIds = LandingPad->TypeIds;
unsigned SizeAction = 0; unsigned SizeAction = 0;
if (LandingPad.IsFilter) { if (LandingPad->IsFilter) {
Asm->EmitSLEB128Bytes(-1); Asm->EmitSLEB128Bytes(-1);
Asm->EOL("TypeInfo index"); Asm->EOL("TypeInfo index");
Asm->EmitSLEB128Bytes(0); Asm->EmitSLEB128Bytes(0);
@ -3111,6 +3161,7 @@ private:
} }
} }
} }
}
// Emit the type ids. // Emit the type ids.
for (unsigned M = TypeInfos.size(); M; --M) { for (unsigned M = TypeInfos.size(); M; --M) {