mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-23 19:59:57 +00:00
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:
parent
02031c0ff8
commit
73ef58ab92
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user