Integrate exception filter support and exception catch support. This

simplifies the code in DwarfWriter, allows for multiple filters and
makes it trivial to specify filters accompanied by cleanups or catch-all
specifications (see next patch).  What a deal!  Patch blessed by Anton.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37398 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan Sands 2007-06-02 16:53:42 +00:00
parent 02031c0ff8
commit 73ef58ab92
4 changed files with 72 additions and 72 deletions

View File

@ -960,16 +960,13 @@ struct LandingPadInfo {
SmallVector<unsigned, 1> EndLabels; // Labels after invoke. SmallVector<unsigned, 1> EndLabels; // Labels after invoke.
unsigned LandingPadLabel; // Label at beginning of landing pad. unsigned LandingPadLabel; // Label at beginning of landing pad.
Function *Personality; // Personality function. Function *Personality; // Personality function.
std::vector<unsigned> TypeIds; // List of type ids. std::vector<int> TypeIds; // List of type ids (filters negative)
bool IsFilter; // Indicate if the landing pad is a
// throw filter.
LandingPadInfo(MachineBasicBlock *MBB) LandingPadInfo(MachineBasicBlock *MBB)
: LandingPadBlock(MBB) : LandingPadBlock(MBB)
, LandingPadLabel(0) , LandingPadLabel(0)
, Personality(NULL) , Personality(NULL)
, TypeIds() , TypeIds()
, IsFilter(false)
{} {}
}; };
@ -1021,6 +1018,10 @@ private:
// //
std::vector<GlobalVariable *> TypeInfos; 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 // Personalities - Vector of all personality functions ever seen. Used to emit
// common EH frames. // common EH frames.
std::vector<Function *> Personalities; std::vector<Function *> Personalities;
@ -1213,20 +1214,25 @@ public:
const std::vector<Function *>& getPersonalities() const { const std::vector<Function *>& getPersonalities() const {
return Personalities; return Personalities;
} }
/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad. /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
/// ///
void addCatchTypeInfo(MachineBasicBlock *LandingPad, void addCatchTypeInfo(MachineBasicBlock *LandingPad,
std::vector<GlobalVariable *> &TyInfo); 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 /// getTypeIDFor - Return the type id for the specified typeinfo. This is
/// function wide. /// function wide.
unsigned getTypeIDFor(GlobalVariable *TI); 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 /// TidyLandingPads - Remap landing pad labels and remove any deleted landing
/// pads. /// pads.
void TidyLandingPads(); void TidyLandingPads();
@ -1242,7 +1248,13 @@ public:
const std::vector<GlobalVariable *> &getTypeInfos() const { const std::vector<GlobalVariable *> &getTypeInfos() const {
return TypeInfos; 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 /// getPersonality - Return a personality function if available. The presence
/// of one is required to emit exception handling info. /// of one is required to emit exception handling info.
Function *getPersonality() const; Function *getPersonality() const;

View File

@ -2896,13 +2896,10 @@ private:
/// EquivPads - Whether two landing pads have equivalent actions. /// EquivPads - Whether two landing pads have equivalent actions.
static bool EquivPads(const LandingPadInfo *L, const LandingPadInfo *R) { static bool EquivPads(const LandingPadInfo *L, const LandingPadInfo *R) {
const std::vector<unsigned> &LIds = L->TypeIds; const std::vector<int> &LIds = L->TypeIds;
const std::vector<unsigned> &RIds = R->TypeIds; const std::vector<int> &RIds = R->TypeIds;
unsigned LSize = LIds.size(), RSize = RIds.size(); unsigned LSize = LIds.size(), RSize = RIds.size();
if (L->IsFilter != R->IsFilter)
return false;
if (LSize != RSize) if (LSize != RSize)
return false; return false;
@ -2915,14 +2912,10 @@ private:
/// PadLT - An order on landing pads, with EquivPads as order equivalence. /// PadLT - An order on landing pads, with EquivPads as order equivalence.
static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) { static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
const std::vector<unsigned> &LIds = L->TypeIds; const std::vector<int> &LIds = L->TypeIds;
const std::vector<unsigned> &RIds = R->TypeIds; const std::vector<int> &RIds = R->TypeIds;
unsigned LSize = LIds.size(), RSize = RIds.size(); unsigned LSize = LIds.size(), RSize = RIds.size();
if (L->IsFilter != R->IsFilter)
// Make filters come last
return L->IsFilter < R->IsFilter;
if (LSize != RSize) if (LSize != RSize)
return LSize < RSize; return LSize < RSize;
@ -2972,6 +2965,7 @@ private:
MMI->TidyLandingPads(); MMI->TidyLandingPads();
const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
if (PadInfos.empty()) return; if (PadInfos.empty()) return;
@ -2985,11 +2979,6 @@ private:
// Gather first action index for each landing pad site. // Gather first action index for each landing pad site.
SmallVector<unsigned, 32> Actions; 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. // Compute sizes for exception table.
unsigned SizeSites = 0; unsigned SizeSites = 0;
unsigned SizeActions = 0; unsigned SizeActions = 0;
@ -3003,24 +2992,15 @@ private:
unsigned SizeSiteActions = 0; unsigned SizeSiteActions = 0;
if (!i || !EquivPads(LandingPad, LandingPads[i-1])) { if (!i || !EquivPads(LandingPad, LandingPads[i-1])) {
const std::vector<unsigned> &TypeIds = LandingPad->TypeIds; const std::vector<int> &TypeIds = LandingPad->TypeIds;
unsigned SizeAction = 0; unsigned SizeAction = 0;
if (LandingPad->IsFilter) { if (TypeIds.empty()) {
// 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()) {
FirstAction = 0; FirstAction = 0;
} else { } else {
// Gather the action sizes // Gather the action sizes
for (unsigned j = 0, M = TypeIds.size(); j != M; ++j) { for (unsigned j = 0, M = TypeIds.size(); j != M; ++j) {
unsigned TypeID = TypeIds[j]; int TypeID = TypeIds[j];
unsigned SizeTypeID = Asm->SizeSLEB128(TypeID); unsigned SizeTypeID = Asm->SizeSLEB128(TypeID);
signed Action = j ? -(SizeAction + SizeTypeID) : 0; signed Action = j ? -(SizeAction + SizeTypeID) : 0;
SizeAction = SizeTypeID + Asm->SizeSLEB128(Action); SizeAction = SizeTypeID + Asm->SizeSLEB128(Action);
@ -3140,25 +3120,18 @@ private:
for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
if (!i || Actions[i] != Actions[i-1]) { if (!i || Actions[i] != Actions[i-1]) {
const LandingPadInfo *LandingPad = LandingPads[i]; const LandingPadInfo *LandingPad = LandingPads[i];
const std::vector<unsigned> &TypeIds = LandingPad->TypeIds; const std::vector<int> &TypeIds = LandingPad->TypeIds;
unsigned SizeAction = 0; unsigned SizeAction = 0;
if (LandingPad->IsFilter) { for (unsigned j = 0, M = TypeIds.size(); j < M; ++j) {
Asm->EmitSLEB128Bytes(-1); int TypeID = TypeIds[j];
unsigned SizeTypeID = Asm->SizeSLEB128(TypeID);
Asm->EmitSLEB128Bytes(TypeID);
Asm->EOL("TypeInfo index"); 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"); 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");
}
} }
} }
} }
@ -3180,16 +3153,11 @@ private:
Asm->EOL("TypeInfo"); Asm->EOL("TypeInfo");
} }
// Emit the filter typeinfo. // Emit the filter typeids.
if (Filter) { for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
const std::vector<unsigned> &TypeIds = Filter->TypeIds; unsigned TypeID = FilterIds[j];
for (unsigned j = 0, M = TypeIds.size(); j < M; ++j) { Asm->EmitSLEB128Bytes(TypeID);
unsigned TypeID = TypeIds[j]; Asm->EOL("Filter TypeInfo index");
Asm->EmitSLEB128Bytes(TypeID);
Asm->EOL("TypeInfo index");
}
Asm->EmitSLEB128Bytes(0);
Asm->EOL("End of filter typeinfo");
} }
Asm->EmitAlignment(2); Asm->EmitAlignment(2);

View File

@ -1521,6 +1521,7 @@ void MachineModuleInfo::EndFunction() {
// Clean up exception info. // Clean up exception info.
LandingPads.clear(); LandingPads.clear();
TypeInfos.clear(); TypeInfos.clear();
FilterIds.clear();
} }
/// getDescFor - Convert a Value to a debug information descriptor. /// getDescFor - Convert a Value to a debug information descriptor.
@ -1708,12 +1709,16 @@ void MachineModuleInfo::addCatchTypeInfo(MachineBasicBlock *LandingPad,
for (unsigned N = TyInfo.size(); N; --N) for (unsigned N = TyInfo.size(); N; --N)
LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1])); 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); 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 /// TidyLandingPads - Remap landing pad labels and remove any deleted landing
@ -1760,6 +1765,20 @@ unsigned MachineModuleInfo::getTypeIDFor(GlobalVariable *TI) {
return TypeInfos.size(); 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. /// getPersonality - Return the personality function for the current function.
Function *MachineModuleInfo::getPersonality() const { Function *MachineModuleInfo::getPersonality() const {
// FIXME: Until PR1414 will be fixed, we're using 1 personality function per // FIXME: Until PR1414 will be fixed, we're using 1 personality function per

View File

@ -2611,8 +2611,6 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
isa<Function>(CE->getOperand(0)) && isa<Function>(CE->getOperand(0)) &&
"Personality should be a function"); "Personality should be a function");
MMI->addPersonality(CurMBB, cast<Function>(CE->getOperand(0))); MMI->addPersonality(CurMBB, cast<Function>(CE->getOperand(0)));
if (Intrinsic == Intrinsic::eh_filter)
MMI->setIsFilterLandingPad(CurMBB);
// Gather all the type infos for this landing pad and pass them along to // Gather all the type infos for this landing pad and pass them along to
// MachineModuleInfo. // MachineModuleInfo.
@ -2624,7 +2622,10 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
"TypeInfo must be a global variable or NULL"); "TypeInfo must be a global variable or NULL");
TyInfo.push_back(GV); TyInfo.push_back(GV);
} }
MMI->addCatchTypeInfo(CurMBB, TyInfo); if (Intrinsic == Intrinsic::eh_filter)
MMI->addFilterTypeInfo(CurMBB, TyInfo);
else
MMI->addCatchTypeInfo(CurMBB, TyInfo);
// Mark exception selector register as live in. // Mark exception selector register as live in.
unsigned Reg = TLI.getExceptionSelectorRegister(); unsigned Reg = TLI.getExceptionSelectorRegister();