aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2007-06-02 16:53:42 +0000
committerDuncan Sands <baldrick@free.fr>2007-06-02 16:53:42 +0000
commit73ef58ab92d5cd23b119b7f206e5f8a8c529098d (patch)
tree6cf1db0c4b0ff8d89c195a92d8d25d19b38b257c
parent02031c0ff8ad48acdb8c4a4058c4fafe600423e1 (diff)
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
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h36
-rw-r--r--lib/CodeGen/DwarfWriter.cpp74
-rw-r--r--lib/CodeGen/MachineModuleInfo.cpp27
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp7
4 files changed, 72 insertions, 72 deletions
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
index c13ba51752..790433e8b4 100644
--- a/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -960,16 +960,13 @@ struct LandingPadInfo {
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)
{}
};
@@ -1021,6 +1018,10 @@ private:
//
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;
@@ -1213,20 +1214,25 @@ public:
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();
@@ -1242,7 +1248,13 @@ public:
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;
diff --git a/lib/CodeGen/DwarfWriter.cpp b/lib/CodeGen/DwarfWriter.cpp
index 7e97788bc1..5ab399705a 100644
--- a/lib/CodeGen/DwarfWriter.cpp
+++ b/lib/CodeGen/DwarfWriter.cpp
@@ -2896,13 +2896,10 @@ private:
/// 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;
@@ -2915,14 +2912,10 @@ private:
/// 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;
@@ -2972,6 +2965,7 @@ private:
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;
@@ -2985,11 +2979,6 @@ private:
// 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;
@@ -3003,24 +2992,15 @@ private:
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);
@@ -3140,25 +3120,18 @@ private:
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");
- }
}
}
}
@@ -3180,16 +3153,11 @@ private:
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);
diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp
index 564c070bc3..32d8394527 100644
--- a/lib/CodeGen/MachineModuleInfo.cpp
+++ b/lib/CodeGen/MachineModuleInfo.cpp
@@ -1521,6 +1521,7 @@ void MachineModuleInfo::EndFunction() {
// Clean up exception info.
LandingPads.clear();
TypeInfos.clear();
+ FilterIds.clear();
}
/// 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)
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
@@ -1760,6 +1765,20 @@ unsigned MachineModuleInfo::getTypeIDFor(GlobalVariable *TI) {
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
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index cfdf6d0ea5..6b6834bffc 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2611,8 +2611,6 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
isa<Function>(CE->getOperand(0)) &&
"Personality should be a function");
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
// MachineModuleInfo.
@@ -2624,7 +2622,10 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
"TypeInfo must be a global variable or NULL");
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.
unsigned Reg = TLI.getExceptionSelectorRegister();