summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp73
-rw-r--r--llvm/test/CodeGen/X86/catchpad-weight.ll85
-rw-r--r--llvm/test/CodeGen/X86/seh-safe-div-win32.ll4
-rw-r--r--llvm/test/CodeGen/X86/seh-safe-div.ll8
-rw-r--r--llvm/test/CodeGen/X86/win-catchpad.ll6
5 files changed, 140 insertions, 36 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 70a6f918657..3d483464f65 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -64,6 +64,7 @@
#include "llvm/Target/TargetSelectionDAGInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include <algorithm>
+#include <utility>
using namespace llvm;
#define DEBUG_TYPE "isel"
@@ -1243,50 +1244,66 @@ void SelectionDAGBuilder::visitCleanupPad(const CleanupPadInst &CPI) {
/// destination, but in the machine CFG, we enumerate all the possible blocks.
/// This function skips over imaginary basic blocks that hold catchpad,
/// terminatepad, or catchendpad instructions, and finds all the "real" machine
-/// basic block destinations.
-static void
-findUnwindDestinations(FunctionLoweringInfo &FuncInfo,
- const BasicBlock *EHPadBB,
- SmallVectorImpl<MachineBasicBlock *> &UnwindDests) {
+/// basic block destinations. As those destinations may not be successors of
+/// EHPadBB, here we also calculate the edge weight to those destinations. The
+/// passed-in Weight is the edge weight to EHPadBB.
+static void findUnwindDestinations(
+ FunctionLoweringInfo &FuncInfo, const BasicBlock *EHPadBB, uint32_t Weight,
+ SmallVectorImpl<std::pair<MachineBasicBlock *, uint32_t>> &UnwindDests) {
EHPersonality Personality =
classifyEHPersonality(FuncInfo.Fn->getPersonalityFn());
bool IsMSVCCXX = Personality == EHPersonality::MSVC_CXX;
bool IsCoreCLR = Personality == EHPersonality::CoreCLR;
+
while (EHPadBB) {
const Instruction *Pad = EHPadBB->getFirstNonPHI();
+ BasicBlock *NewEHPadBB = nullptr;
if (isa<LandingPadInst>(Pad)) {
// Stop on landingpads. They are not funclets.
- UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]);
+ UnwindDests.emplace_back(FuncInfo.MBBMap[EHPadBB], Weight);
break;
} else if (isa<CleanupPadInst>(Pad)) {
// Stop on cleanup pads. Cleanups are always funclet entries for all known
// personalities.
- UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]);
- UnwindDests.back()->setIsEHFuncletEntry();
+ UnwindDests.emplace_back(FuncInfo.MBBMap[EHPadBB], Weight);
+ UnwindDests.back().first->setIsEHFuncletEntry();
break;
} else if (const auto *CPI = dyn_cast<CatchPadInst>(Pad)) {
// Add the catchpad handler to the possible destinations.
- UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]);
+ UnwindDests.emplace_back(FuncInfo.MBBMap[EHPadBB], Weight);
// In MSVC C++, catchblocks are funclets and need prologues.
if (IsMSVCCXX || IsCoreCLR)
- UnwindDests.back()->setIsEHFuncletEntry();
- EHPadBB = CPI->getUnwindDest();
- } else if (const auto *CEPI = dyn_cast<CatchEndPadInst>(Pad)) {
- EHPadBB = CEPI->getUnwindDest();
- } else if (const auto *CEPI = dyn_cast<CleanupEndPadInst>(Pad)) {
- EHPadBB = CEPI->getUnwindDest();
+ UnwindDests.back().first->setIsEHFuncletEntry();
+ NewEHPadBB = CPI->getUnwindDest();
+ } else if (const auto *CEPI = dyn_cast<CatchEndPadInst>(Pad))
+ NewEHPadBB = CEPI->getUnwindDest();
+ else if (const auto *CEPI = dyn_cast<CleanupEndPadInst>(Pad))
+ NewEHPadBB = CEPI->getUnwindDest();
+ else
+ continue;
+
+ BranchProbabilityInfo *BPI = FuncInfo.BPI;
+ if (BPI && NewEHPadBB) {
+ // When BPI is available, the calculated weight cannot be zero as zero
+ // will be turned to a default weight in MachineBlockFrequencyInfo.
+ Weight = std::max<uint32_t>(
+ BPI->getEdgeProbability(EHPadBB, NewEHPadBB).scale(Weight), 1);
}
+ EHPadBB = NewEHPadBB;
}
}
void SelectionDAGBuilder::visitCleanupRet(const CleanupReturnInst &I) {
// Update successor info.
- // FIXME: The weights for catchpads will be wrong.
- SmallVector<MachineBasicBlock *, 1> UnwindDests;
- findUnwindDestinations(FuncInfo, I.getUnwindDest(), UnwindDests);
- for (MachineBasicBlock *UnwindDest : UnwindDests) {
- UnwindDest->setIsEHPad();
- addSuccessorWithWeight(FuncInfo.MBB, UnwindDest);
+ SmallVector<std::pair<MachineBasicBlock *, uint32_t>, 1> UnwindDests;
+ auto UnwindDest = I.getUnwindDest();
+ BranchProbabilityInfo *BPI = FuncInfo.BPI;
+ uint32_t UnwindDestWeight =
+ BPI ? BPI->getEdgeWeight(FuncInfo.MBB->getBasicBlock(), UnwindDest) : 0;
+ findUnwindDestinations(FuncInfo, UnwindDest, UnwindDestWeight, UnwindDests);
+ for (auto &UnwindDest : UnwindDests) {
+ UnwindDest.first->setIsEHPad();
+ addSuccessorWithWeight(FuncInfo.MBB, UnwindDest.first, UnwindDest.second);
}
// Create the terminator node.
@@ -2128,15 +2145,17 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
CopyToExportRegsIfNeeded(&I);
}
- SmallVector<MachineBasicBlock *, 1> UnwindDests;
- findUnwindDestinations(FuncInfo, EHPadBB, UnwindDests);
+ SmallVector<std::pair<MachineBasicBlock *, uint32_t>, 1> UnwindDests;
+ BranchProbabilityInfo *BPI = FuncInfo.BPI;
+ uint32_t EHPadBBWeight =
+ BPI ? BPI->getEdgeWeight(InvokeMBB->getBasicBlock(), EHPadBB) : 0;
+ findUnwindDestinations(FuncInfo, EHPadBB, EHPadBBWeight, UnwindDests);
// Update successor info.
- // FIXME: The weights for catchpads will be wrong.
addSuccessorWithWeight(InvokeMBB, Return);
- for (MachineBasicBlock *UnwindDest : UnwindDests) {
- UnwindDest->setIsEHPad();
- addSuccessorWithWeight(InvokeMBB, UnwindDest);
+ for (auto &UnwindDest : UnwindDests) {
+ UnwindDest.first->setIsEHPad();
+ addSuccessorWithWeight(InvokeMBB, UnwindDest.first, UnwindDest.second);
}
// Drop into normal successor.
diff --git a/llvm/test/CodeGen/X86/catchpad-weight.ll b/llvm/test/CodeGen/X86/catchpad-weight.ll
new file mode 100644
index 00000000000..e646d36aa80
--- /dev/null
+++ b/llvm/test/CodeGen/X86/catchpad-weight.ll
@@ -0,0 +1,85 @@
+; RUN: llc -march=x86-64 -print-machineinstrs=expand-isel-pseudos %s -o /dev/null 2>&1 | FileCheck %s
+
+; Check if the edge weight to the catchpad is calculated correctly.
+
+; CHECK: Successors according to CFG: BB#3(1048575) BB#1(1) BB#4(1) BB#6(1) BB#8(1)
+
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64--windows-msvc18.0.0"
+
+%rtti.TypeDescriptor7 = type { i8**, i8*, [8 x i8] }
+%struct.HasDtor = type { i8 }
+
+$"\01??_R0?AUA@@@8" = comdat any
+
+$"\01??_R0?AUB@@@8" = comdat any
+
+$"\01??_R0?AUC@@@8" = comdat any
+
+@"\01??_7type_info@@6B@" = external constant i8*
+@"\01??_R0?AUA@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUA@@\00" }, comdat
+@"\01??_R0?AUB@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUB@@\00" }, comdat
+@"\01??_R0?AUC@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUC@@\00" }, comdat
+
+; Function Attrs: uwtable
+define i32 @main() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+entry:
+ %o = alloca %struct.HasDtor, align 1
+ %0 = getelementptr inbounds %struct.HasDtor, %struct.HasDtor* %o, i64 0, i32 0
+ call void @llvm.lifetime.start(i64 1, i8* %0) #4
+ invoke void @"\01?may_throw@@YAXXZ"()
+ to label %try.cont unwind label %catch.dispatch
+
+catch.dispatch: ; preds = %entry
+ %1 = catchpad [%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8", i32 0, i8* null]
+ to label %catch.5 unwind label %catch.dispatch.1
+
+catch.5: ; preds = %catch.dispatch
+ catchret %1 to label %try.cont
+
+try.cont: ; preds = %entry, %catch, %catch.3, %catch.5
+ call void @"\01??1HasDtor@@QEAA@XZ"(%struct.HasDtor* nonnull %o) #4
+ call void @llvm.lifetime.end(i64 1, i8* %0) #4
+ ret i32 0
+
+catch.dispatch.1: ; preds = %catch.dispatch
+ %2 = catchpad [%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8", i32 0, i8* null]
+ to label %catch.3 unwind label %catch.dispatch.2
+
+catch.3: ; preds = %catch.dispatch.1
+ catchret %2 to label %try.cont
+
+catch.dispatch.2: ; preds = %catch.dispatch.1
+ %3 = catchpad [%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8", i32 0, i8* null]
+ to label %catch unwind label %catchendblock
+
+catch: ; preds = %catch.dispatch.2
+ catchret %3 to label %try.cont
+
+catchendblock: ; preds = %catch.dispatch.2
+ catchendpad unwind label %ehcleanup
+
+ehcleanup: ; preds = %catchendblock
+ %4 = cleanuppad []
+ call void @"\01??1HasDtor@@QEAA@XZ"(%struct.HasDtor* nonnull %o) #4
+ cleanupret %4 unwind to caller
+}
+
+; Function Attrs: nounwind argmemonly
+declare void @llvm.lifetime.start(i64, i8* nocapture) #1
+
+declare void @"\01?may_throw@@YAXXZ"() #2
+
+declare i32 @__CxxFrameHandler3(...)
+
+; Function Attrs: nounwind
+declare void @"\01??1HasDtor@@QEAA@XZ"(%struct.HasDtor*) #3
+
+; Function Attrs: nounwind argmemonly
+declare void @llvm.lifetime.end(i64, i8* nocapture) #1
+
+attributes #0 = { uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind argmemonly }
+attributes #2 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #3 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #4 = { nounwind }
diff --git a/llvm/test/CodeGen/X86/seh-safe-div-win32.ll b/llvm/test/CodeGen/X86/seh-safe-div-win32.ll
index d17f2217ca2..7f83b0c6466 100644
--- a/llvm/test/CodeGen/X86/seh-safe-div-win32.ll
+++ b/llvm/test/CodeGen/X86/seh-safe-div-win32.ll
@@ -71,13 +71,13 @@ __try.cont:
; Landing pad code
-; CHECK: [[lpad1:LBB0_[0-9]+]]: # %lpad1
+; CHECK: [[lpad0:LBB0_[0-9]+]]: # %lpad0
; Restore SP
; CHECK: movl {{.*}}(%ebp), %esp
; CHECK: calll _puts
; CHECK: jmp [[cont_bb]]
-; CHECK: [[lpad0:LBB0_[0-9]+]]: # %lpad0
+; CHECK: [[lpad1:LBB0_[0-9]+]]: # %lpad1
; Restore SP
; CHECK: movl {{.*}}(%ebp), %esp
; CHECK: calll _puts
diff --git a/llvm/test/CodeGen/X86/seh-safe-div.ll b/llvm/test/CodeGen/X86/seh-safe-div.ll
index 809d261b7d7..1c7318b5614 100644
--- a/llvm/test/CodeGen/X86/seh-safe-div.ll
+++ b/llvm/test/CodeGen/X86/seh-safe-div.ll
@@ -73,14 +73,14 @@ __try.cont:
; Landing pad code
-; CHECK: [[lpad1:\.LBB0_[0-9]+]]: # %lpad1
+; CHECK: [[lpad0:\.LBB0_[0-9]+]]: # %lpad0
; CHECK: callq puts
-; CHECK: movl $-2, [[rloc]]
+; CHECK: movl $-1, [[rloc]]
; CHECK: jmp [[cont_bb]]
-; CHECK: [[lpad0:\.LBB0_[0-9]+]]: # %lpad0
+; CHECK: [[lpad1:\.LBB0_[0-9]+]]: # %lpad1
; CHECK: callq puts
-; CHECK: movl $-1, [[rloc]]
+; CHECK: movl $-2, [[rloc]]
; CHECK: jmp [[cont_bb]]
; CHECK: .seh_handlerdata
diff --git a/llvm/test/CodeGen/X86/win-catchpad.ll b/llvm/test/CodeGen/X86/win-catchpad.ll
index 78a8fcfc8f4..7761839b7a8 100644
--- a/llvm/test/CodeGen/X86/win-catchpad.ll
+++ b/llvm/test/CodeGen/X86/win-catchpad.ll
@@ -74,13 +74,13 @@ catchendblock: ; preds = %catch, %catch.2, %c
; X86: [[contbb:LBB0_[0-9]+]]: # %try.cont
; X86: retl
-; FIXME: These should be de-duplicated.
-; X86: [[restorebb2:LBB0_[0-9]+]]: # %invoke.cont.3
+; X86: [[restorebb1:LBB0_[0-9]+]]: # %invoke.cont.2
; X86: movl -16(%ebp), %esp
; X86: addl $12, %ebp
; X86: jmp [[contbb]]
-; X86: [[restorebb1:LBB0_[0-9]+]]: # %invoke.cont.2
+; FIXME: These should be de-duplicated.
+; X86: [[restorebb2:LBB0_[0-9]+]]: # %invoke.cont.3
; X86: movl -16(%ebp), %esp
; X86: addl $12, %ebp
; X86: jmp [[contbb]]
OpenPOWER on IntegriCloud