aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/MachineModuleInfo.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2007-09-05 11:27:52 +0000
committerDuncan Sands <baldrick@free.fr>2007-09-05 11:27:52 +0000
commit57810cdac4c842b4b395d2a0b2fae406aacb3ee4 (patch)
tree4180061ffab3b240bdcb49ec8d8d59f57e317b03 /lib/CodeGen/MachineModuleInfo.cpp
parentc3536b8ecbe49b60cdf9ab76ca79dcea765f2802 (diff)
Fix PR1628. When exception handling is turned on,
labels are generated bracketing each call (not just invokes). This is used to generate entries in the exception table required by the C++ personality. However it gets in the way of tail-merging. This patch solves the problem by no longer placing labels around ordinary calls. Instead we generate entries in the exception table that cover every instruction in the function that wasn't covered by an invoke range (the range given by the labels around the invoke). As an optimization, such entries are only generated for parts of the function that contain a call, since for the moment those are the only instructions that can throw an exception [1]. As a happy consequence, we now get a smaller exception table, since the same region can cover many calls. While there, I also implemented folding of invoke ranges - successive ranges are merged when safe to do so. Finally, if a selector contains only a cleanup, there's a special shorthand for it - place a 0 in the call-site entry. I implemented this while there. As a result, the exception table output (excluding filters) is now optimal - it cannot be made smaller [2]. The problem with throw filters is that folding them optimally is hard, and the benefit of folding them is minimal. [1] I tested that having trapping instructions (eg divide by zero) in such a region doesn't cause trouble. [2] It could be made smaller with the help of higher layers, eg by having branch folding reorder basic blocks ending in invokes with the same landing pad so they follow each other. I don't know if this is worth doing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41718 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineModuleInfo.cpp')
-rw-r--r--lib/CodeGen/MachineModuleInfo.cpp24
1 files changed, 16 insertions, 8 deletions
diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp
index 62224fdca8..8360745ff1 100644
--- a/lib/CodeGen/MachineModuleInfo.cpp
+++ b/lib/CodeGen/MachineModuleInfo.cpp
@@ -1740,22 +1740,18 @@ void MachineModuleInfo::TidyLandingPads() {
LandingPadInfo &LandingPad = LandingPads[i];
LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel);
- if (!LandingPad.LandingPadBlock)
- // Must not have cleanups if no landing pad.
- LandingPad.TypeIds.clear();
-
// Special case: we *should* emit LPs with null LP MBB. This indicates
// "rethrow" case.
if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
LandingPads.erase(LandingPads.begin() + i);
continue;
}
-
+
for (unsigned j=0; j != LandingPads[i].BeginLabels.size(); ) {
unsigned BeginLabel = MappedLabel(LandingPad.BeginLabels[j]);
unsigned EndLabel = MappedLabel(LandingPad.EndLabels[j]);
-
-
+
+
if (!BeginLabel || !EndLabel) {
LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
@@ -1766,7 +1762,19 @@ void MachineModuleInfo::TidyLandingPads() {
LandingPad.EndLabels[j] = EndLabel;
++j;
}
-
+
+ // Remove landing pads with no try-ranges.
+ if (!LandingPads[i].BeginLabels.size()) {
+ LandingPads.erase(LandingPads.begin() + i);
+ continue;
+ }
+
+ // If there is no landing pad, ensure that the list of typeids is empty.
+ // If the only typeid is a cleanup, this is the same as having no typeids.
+ if (!LandingPad.LandingPadBlock ||
+ (LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0]))
+ LandingPad.TypeIds.clear();
+
++i;
}
}