#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/CFG.h"
+#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
Function &F;
const TargetLowering &TLI;
- DominatorTree *DT;
+ DomTreeUpdater *DTU;
const TargetTransformInfo *TTI;
/// Return the exception object from the value passed into
public:
DwarfEHPrepare(CodeGenOpt::Level OptLevel_, FunctionCallee &RewindFunction_,
- Function &F_, const TargetLowering &TLI_, DominatorTree *DT_,
+ Function &F_, const TargetLowering &TLI_, DomTreeUpdater *DTU_,
const TargetTransformInfo *TTI_)
: OptLevel(OptLevel_), RewindFunction(RewindFunction_), F(F_), TLI(TLI_),
- DT(DT_), TTI(TTI_) {}
+ DTU(DTU_), TTI(TTI_) {}
bool run();
};
size_t DwarfEHPrepare::pruneUnreachableResumes(
SmallVectorImpl<ResumeInst *> &Resumes,
SmallVectorImpl<LandingPadInst *> &CleanupLPads) {
+ assert(DTU && "Should have DomTreeUpdater here.");
+
BitVector ResumeReachable(Resumes.size());
size_t ResumeIndex = 0;
for (auto *RI : Resumes) {
for (auto *LP : CleanupLPads) {
- if (isPotentiallyReachable(LP, RI, nullptr, DT)) {
+ if (isPotentiallyReachable(LP, RI, nullptr, &DTU->getDomTree())) {
ResumeReachable.set(ResumeIndex);
break;
}
BasicBlock *BB = RI->getParent();
new UnreachableInst(Ctx, RI);
RI->eraseFromParent();
- simplifyCFG(BB, *TTI);
+ simplifyCFG(BB, *TTI, DTU);
}
}
Resumes.resize(ResumesLeft);
return true;
}
+ std::vector<DominatorTree::UpdateType> Updates;
+ Updates.reserve(Resumes.size());
+
BasicBlock *UnwindBB = BasicBlock::Create(Ctx, "unwind_resume", &F);
PHINode *PN = PHINode::Create(Type::getInt8PtrTy(Ctx), ResumesLeft, "exn.obj",
UnwindBB);
for (ResumeInst *RI : Resumes) {
BasicBlock *Parent = RI->getParent();
BranchInst::Create(UnwindBB, Parent);
+ Updates.push_back({DominatorTree::Insert, Parent, UnwindBB});
Value *ExnObj = GetExceptionObject(RI);
PN->addIncoming(ExnObj, Parent);
// We never expect _Unwind_Resume to return.
CI->setDoesNotReturn();
new UnreachableInst(Ctx, UnwindBB);
+
+ if (DTU && RequireAndPreserveDomTree)
+ DTU->applyUpdatesPermissive(Updates);
+
return true;
}
-bool DwarfEHPrepare::run() { return InsertUnwindResumeCalls(); }
+bool DwarfEHPrepare::run() {
+ assert(((OptLevel == CodeGenOpt::None) ||
+ (DTU &&
+ DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full))) &&
+ "Original domtree is invalid?");
+
+ bool Changed = InsertUnwindResumeCalls();
+
+ assert(((OptLevel == CodeGenOpt::None || !RequireAndPreserveDomTree) ||
+ (DTU &&
+ DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full))) &&
+ "Original domtree is invalid?");
+
+ return Changed;
+}
+
+static bool prepareDwarfEH(CodeGenOpt::Level OptLevel,
+ FunctionCallee &RewindFunction, Function &F,
+ const TargetLowering &TLI, DominatorTree *DT,
+ const TargetTransformInfo *TTI) {
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+
+ return DwarfEHPrepare(OptLevel, RewindFunction, F, TLI, DT ? &DTU : nullptr,
+ TTI)
+ .run();
+};
namespace {
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
}
- return DwarfEHPrepare(OptLevel, RewindFunction, F, TLI, DT, TTI).run();
+ return prepareDwarfEH(OptLevel, RewindFunction, F, TLI, DT, TTI);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
if (OptLevel != CodeGenOpt::None) {
AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<TargetTransformInfoWrapperPass>();
+ if (RequireAndPreserveDomTree)
+ AU.addPreserved<DominatorTreeWrapperPass>();
}
}
-; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic -simplifycfg-require-and-preserve-domtree=0 -o - %s | FileCheck %s
-; RUN: llc -mtriple=aarch64_be-none-linux-gnu -relocation-model=pic -simplifycfg-require-and-preserve-domtree=0 -o - %s | FileCheck %s
+; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic -simplifycfg-require-and-preserve-domtree=1 -o - %s | FileCheck %s
+; RUN: llc -mtriple=aarch64_be-none-linux-gnu -relocation-model=pic -simplifycfg-require-and-preserve-domtree=1 -o - %s | FileCheck %s
; Make sure exception-handling PIC code can be linked correctly. An alternative
; to the sequence described below would have .gcc_except_table itself writable
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -verify-machineinstrs
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -verify-machineinstrs
; <rdar://problem/9187612>
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32"
; Assertion `Encoding == DW_EH_PE_absptr && "Can handle absptr encoding only"' failed.
; Broken in r208166, fixed in 208715.
-; RUN: llc -mtriple=arm-linux-androideabi -o - -filetype=asm -relocation-model=pic -simplifycfg-require-and-preserve-domtree=0 %s
+; RUN: llc -mtriple=arm-linux-androideabi -o - -filetype=asm -relocation-model=pic -simplifycfg-require-and-preserve-domtree=1 %s
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
target triple = "armv4t--linux-androideabi"
-; RUN: llc -mtriple=armv7-none-linux-gnueabi -simplifycfg-require-and-preserve-domtree=0 < %s | FileCheck %s
+; RUN: llc -mtriple=armv7-none-linux-gnueabi -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
@_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
@_ZTS3Foo = linkonce_odr constant [5 x i8] c"3Foo\00"
-; RUN: llc -mtriple=arm-netbsd-eabi -o - -filetype=asm -simplifycfg-require-and-preserve-domtree=0 %s | \
+; RUN: llc -mtriple=arm-netbsd-eabi -o - -filetype=asm -simplifycfg-require-and-preserve-domtree=1 %s | \
; RUN: FileCheck %s
-; RUN: llc -mtriple=arm-netbsd-eabi -o - -filetype=asm -simplifycfg-require-and-preserve-domtree=0 %s \
+; RUN: llc -mtriple=arm-netbsd-eabi -o - -filetype=asm -simplifycfg-require-and-preserve-domtree=1 %s \
; RUN: -relocation-model=pic | FileCheck -check-prefix=CHECK-PIC %s
; ModuleID = 'test.cc'
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s | FileCheck %s
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32-S64"
target triple = "armv7-none-linux-gnueabi"
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -mtriple=thumb-apple-darwin -arm-global-merge -global-merge-group-by-use=false -global-merge-on-const=true | FileCheck %s
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=thumb-apple-darwin -arm-global-merge -global-merge-group-by-use=false -global-merge-on-const=true | FileCheck %s
; Test the ARMGlobalMerge pass. Use -mtriple=thumb because it has a small
; value for the maximum offset (127).
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 %s -o - | FileCheck %s
-; RUN: llc -mtriple=armv7-linux -exception-model sjlj -simplifycfg-require-and-preserve-domtree=0 %s -o - | FileCheck %s -check-prefix CHECK-LINUX
-; RUN: llc -mtriple=thumbv7-win32 -exception-model sjlj -simplifycfg-require-and-preserve-domtree=0 %s -o - | FileCheck %s -check-prefix CHECK-WIN32
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 %s -o - | FileCheck %s
+; RUN: llc -mtriple=armv7-linux -exception-model sjlj -simplifycfg-require-and-preserve-domtree=1 %s -o - | FileCheck %s -check-prefix CHECK-LINUX
+; RUN: llc -mtriple=thumbv7-win32 -exception-model sjlj -simplifycfg-require-and-preserve-domtree=1 %s -o - | FileCheck %s -check-prefix CHECK-WIN32
target triple = "armv7-apple-ios"
declare i32 @llvm.eh.sjlj.setjmp(i8*)
-; RUN: llc -march=hexagon -simplifycfg-require-and-preserve-domtree=0 < %s | FileCheck %s
+; RUN: llc -march=hexagon -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
; CHECK: .cfi_def_cfa r30
; CHECK: .cfi_offset r31
; CHECK: .cfi_offset r30
-; RUN: llc -march=hexagon -simplifycfg-require-and-preserve-domtree=0 < %s | FileCheck %s
+; RUN: llc -march=hexagon -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
; CHECK: GCC_except_table0:
; CHECK: Call site Encoding = uleb128
-; RUN: llc -march=hexagon -O2 -simplifycfg-require-and-preserve-domtree=0 < %s | FileCheck %s
+; RUN: llc -march=hexagon -O2 -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
; The purpose of this test is to make sure that the packetizer is ignoring
; CFI instructions while forming packet for allocframe. Refer to 7d7d99622
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s | FileCheck %s
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
;; Formerly crashed, see PR 1508
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f128:64:128"
target triple = "powerpc64-unknown-linux-gnu"
; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \
-; RUN: -mattr=-altivec -simplifycfg-require-and-preserve-domtree=0 < %s | \
+; RUN: -mattr=-altivec -simplifycfg-require-and-preserve-domtree=1 < %s | \
; RUN: FileCheck --check-prefixes=ASM,ASM32 %s
; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -mcpu=pwr4 \
-; RUN: -mattr=-altivec -simplifycfg-require-and-preserve-domtree=0 < %s | \
+; RUN: -mattr=-altivec -simplifycfg-require-and-preserve-domtree=1 < %s | \
; RUN: FileCheck --check-prefixes=ASM,ASM64 %s
@_ZTIi = external constant i8*
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -march=sparc -relocation-model=static | FileCheck -check-prefix=V8ABS %s
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -march=sparc -relocation-model=pic | FileCheck -check-prefix=V8PIC %s
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -march=sparcv9 -relocation-model=static | FileCheck -check-prefix=V9ABS %s
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -march=sparcv9 -relocation-model=pic | FileCheck -check-prefix=V9PIC %s
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -march=sparc -relocation-model=static | FileCheck -check-prefix=V8ABS %s
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -march=sparc -relocation-model=pic | FileCheck -check-prefix=V8PIC %s
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -march=sparcv9 -relocation-model=static | FileCheck -check-prefix=V9ABS %s
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -march=sparcv9 -relocation-model=pic | FileCheck -check-prefix=V9PIC %s
%struct.__fundamental_type_info_pseudo = type { %struct.__type_info_pseudo }
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -mtriple=i686-pc-linux-gnu -o - | FileCheck %s --check-prefix=LIN
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -mtriple=i386-pc-mingw32 -o - | FileCheck %s --check-prefix=WIN
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -mtriple=i686-pc-windows-gnu -o - | FileCheck %s --check-prefix=WIN
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -mtriple=x86_64-pc-windows-gnu -o - | FileCheck %s --check-prefix=WIN64
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=i686-pc-linux-gnu -o - | FileCheck %s --check-prefix=LIN
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=i386-pc-mingw32 -o - | FileCheck %s --check-prefix=WIN
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=i686-pc-windows-gnu -o - | FileCheck %s --check-prefix=WIN
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=x86_64-pc-windows-gnu -o - | FileCheck %s --check-prefix=WIN64
; LIN: .cfi_personality 0, __gnat_eh_personality
; LIN: .cfi_lsda 0, .Lexception0
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -mtriple=i386-pc-mingw32
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=i386-pc-mingw32
define void @func() nounwind personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
invoke.cont:
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -frame-pointer=all
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -frame-pointer=all
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32-S128"
target triple = "i386-apple-macosx10.7"
; Check if landing pads are kept in a separate eh section
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -mtriple=i386-unknown-linux-gnu -function-sections -basic-block-sections=all -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=i386-unknown-linux-gnu -function-sections -basic-block-sections=all -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS
@_ZTIb = external dso_local constant i8*
define i32 @_Z3foob(i1 zeroext %0) #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
-; RUN: llc -mtriple=x86_64-pc-linux-gnu -code-model=kernel -simplifycfg-require-and-preserve-domtree=0 %s -o - | FileCheck %s
+; RUN: llc -mtriple=x86_64-pc-linux-gnu -code-model=kernel -simplifycfg-require-and-preserve-domtree=1 %s -o - | FileCheck %s
; CHECK-LABEL: main
; CHECK: .cfi_startproc
; CHECK: .cfi_personality 0, __gxx_personality_v0
-; RUN: opt -mtriple=x86_64-linux-gnu -dwarfehprepare -simplifycfg-require-and-preserve-domtree=0 < %s -S | FileCheck %s
+; RUN: opt -mtriple=x86_64-linux-gnu -dwarfehprepare -simplifycfg-require-and-preserve-domtree=1 < %s -S | FileCheck %s
; Check basic functionality of IR-to-IR DWARF EH preparation. This should
; eliminate resumes. This pass requires a TargetMachine, so we put it under X86
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -mtriple=x86_64 | FileCheck %s --check-prefixes=CHECK,NORMAL
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -mtriple=x86_64 -unique-section-names=false | FileCheck %s --check-prefixes=CHECK,NOUNIQUE
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -mtriple=x86_64 -function-sections | FileCheck %s --check-prefixes=CHECK,SEP
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -mtriple=x86_64 -function-sections -unique-section-names=false | FileCheck %s --check-prefixes=CHECK,SEP_NOUNIQUE
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=x86_64 | FileCheck %s --check-prefixes=CHECK,NORMAL
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=x86_64 -unique-section-names=false | FileCheck %s --check-prefixes=CHECK,NOUNIQUE
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=x86_64 -function-sections | FileCheck %s --check-prefixes=CHECK,SEP
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=x86_64 -function-sections -unique-section-names=false | FileCheck %s --check-prefixes=CHECK,SEP_NOUNIQUE
;; Don't use `,unique` if GNU as<2.35.
-; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -mtriple=x86_64 -function-sections -unique-section-names=false -no-integrated-as | FileCheck %s --check-prefixes=CHECK,SEP_NOUNIQUE_GAS
+; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=x86_64 -function-sections -unique-section-names=false -no-integrated-as | FileCheck %s --check-prefixes=CHECK,SEP_NOUNIQUE_GAS
@_ZTIi = external constant i8*
-; RUN: llc -mtriple x86_64-unknown-unknown -exception-model sjlj -verify-machineinstrs=0 -simplifycfg-require-and-preserve-domtree=0 < %s | FileCheck %s --check-prefix=NUM
-; RUN: llc -mtriple x86_64-unknown-unknown -exception-model sjlj -verify-machineinstrs=0 -simplifycfg-require-and-preserve-domtree=0 < %s | FileCheck %s --check-prefix=SJLJ
+; RUN: llc -mtriple x86_64-unknown-unknown -exception-model sjlj -verify-machineinstrs=0 -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s --check-prefix=NUM
+; RUN: llc -mtriple x86_64-unknown-unknown -exception-model sjlj -verify-machineinstrs=0 -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s --check-prefix=SJLJ
; NUM-COUNT-3: endbr64