summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG
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
commit3c1b7fc0566dceb73b75ad0d06f4ba29d20bf3a0 (patch)
treec5d4affbd0a445b9a7826f3214f55f9831466fa4 /llvm/lib/CodeGen/SelectionDAG
parentb9bf812ba55bdd0d80e45e07316c24551adc7199 (diff)
downloadbcm5719-llvm-3c1b7fc0566dceb73b75ad0d06f4ba29d20bf3a0.tar.gz
bcm5719-llvm-3c1b7fc0566dceb73b75ad0d06f4ba29d20bf3a0.zip
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. llvm-svn: 41718
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp4
1 files changed, 2 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 62bcc32bb4e..a695048a5ad 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2928,7 +2928,7 @@ void SelectionDAGLowering::LowerCallTo(Instruction &I,
Args.push_back(Entry);
}
- if (ExceptionHandling && MMI) {
+ if (ExceptionHandling && MMI && LandingPad) {
// Insert a label before the invoke call to mark the try range. This can be
// used to detect deletion of the invoke via the MachineModuleInfo.
BeginLabel = MMI->NextLabelID();
@@ -2945,7 +2945,7 @@ void SelectionDAGLowering::LowerCallTo(Instruction &I,
setValue(&I, Result.first);
DAG.setRoot(Result.second);
- if (ExceptionHandling && MMI) {
+ if (ExceptionHandling && MMI && LandingPad) {
// Insert a label at the end of the invoke call to mark the try range. This
// can be used to detect deletion of the invoke via the MachineModuleInfo.
EndLabel = MMI->NextLabelID();
OpenPOWER on IntegriCloud