llvm.org GIT mirror llvm / 287b901
[ObjCARC] Add funclet token to ARC marker The inline assembly generated for the ARC autorelease elision marker must have a funclet token if it's emitted inside a funclet, otherwise the inline assembly (and all subsequent code in the funclet) will be marked unreachable by WinEHPrepare. Note that this only applies for the non-O0 case, since at O0, clang emits the autorelease elision marker itself rather than deferring to the backend. The fix for clang is handled in a separate change. Differential Revision: https://reviews.llvm.org/D44641 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@328042 91177308-0d34-0410-b5e6-96231b3b80d8 Shoaib Meenai 2 years ago
2 changed file(s) with 88 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
3030 #include "ObjCARC.h"
3131 #include "ProvenanceAnalysis.h"
3232 #include "llvm/ADT/Statistic.h"
33 #include "llvm/Analysis/EHPersonalities.h"
3334 #include "llvm/IR/Dominators.h"
3435 #include "llvm/IR/InlineAsm.h"
3536 #include "llvm/IR/Operator.h"
7374 SmallPtrSet StoreStrongCalls;
7475
7576 /// Returns true if we eliminated Inst.
76 bool tryToPeepholeInstruction(Function &F, Instruction *Inst,
77 inst_iterator &Iter,
78 SmallPtrSetImpl &DepInsts,
79 SmallPtrSetImpl &Visited,
80 bool &TailOkForStoreStrong);
77 bool
78 tryToPeepholeInstruction(Function &F, Instruction *Inst,
79 inst_iterator &Iter,
80 SmallPtrSetImpl &DepInsts,
81 SmallPtrSetImpl &Visited,
82 bool &TailOkForStoreStrong,
83 DenseMap &BlockColors);
8184
8285 bool optimizeRetainCall(Function &F, Instruction *Retain);
8386
406409 Function &F, Instruction *Inst, inst_iterator &Iter,
407410 SmallPtrSetImpl &DependingInsts,
408411 SmallPtrSetImpl &Visited,
409 bool &TailOkForStoreStrongs) {
412 bool &TailOkForStoreStrongs,
413 DenseMap &BlockColors) {
410414 // Only these library routines return their argument. In particular,
411415 // objc_retainBlock does not necessarily return its argument.
412416 ARCInstKind Class = GetBasicARCInstKind(Inst);
456460 /*isVarArg=*/false),
457461 RVInstMarker->getString(),
458462 /*Constraints=*/"", /*hasSideEffects=*/true);
459 CallInst::Create(IA, "", Inst);
463
464 SmallVector OpBundles;
465 if (!BlockColors.empty()) {
466 const ColorVector &CV = BlockColors.find(Inst->getParent())->second;
467 assert(CV.size() == 1 && "non-unique color for block!");
468 Instruction *EHPad = CV.front()->getFirstNonPHI();
469 if (EHPad->isEHPad())
470 OpBundles.emplace_back("funclet", EHPad);
471 }
472
473 CallInst::Create(IA, None, OpBundles, "", Inst);
460474 }
461475 decline_rv_optimization:
462476 return false;
517531
518532 PA.setAA(&getAnalysis().getAAResults());
519533
534 DenseMap BlockColors;
535 if (F.hasPersonalityFn() &&
536 isFuncletEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
537 BlockColors = colorEHFunclets(F);
538
520539 DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n");
521540
522541 // Track whether it's ok to mark objc_storeStrong calls with the "tail"
540559 // First try to peephole Inst. If there is nothing further we can do in
541560 // terms of undoing objc-arc-expand, process the next inst.
542561 if (tryToPeepholeInstruction(F, Inst, I, DependingInstructions, Visited,
543 TailOkForStoreStrongs))
562 TailOkForStoreStrongs, BlockColors))
544563 continue;
545564
546565 // Otherwise, try to undo objc-arc-expand.
0 ; RUN: opt -mtriple=i686-unknown-windows-msvc -objc-arc-contract -S -o - %s | FileCheck %s
1
2 ; Generated (and lightly modified and cleaned up) from the following source:
3 ; id f();
4 ; void g() {
5 ; try {
6 ; f();
7 ; } catch (...) {
8 ; f();
9 ; }
10 ; }
11
12 define void @"\01?g@@YAXXZ"() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
13 entry:
14 %call = invoke i8* @"\01?f@@YAPAUobjc_object@@XZ"()
15 to label %invoke.cont unwind label %catch.dispatch
16
17 catch.dispatch: ; preds = %entry
18 %0 = catchswitch within none [label %catch] unwind to caller
19
20 catch: ; preds = %catch.dispatch
21 %1 = catchpad within %0 [i8* null, i32 64, i8* null]
22 %call1 = call i8* @"\01?f@@YAPAUobjc_object@@XZ"() [ "funclet"(token %1) ]
23 %2 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call1) [ "funclet"(token %1) ]
24 call void @objc_release(i8* %2) [ "funclet"(token %1) ]
25 br label %catch.1
26
27 catch.1: ; preds = %catch
28 %call2 = call i8* @"\01?f@@YAPAUobjc_object@@XZ"() [ "funclet"(token %1) ]
29 %3 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call2) [ "funclet"(token %1) ]
30 call void @objc_release(i8* %3) [ "funclet"(token %1) ]
31 catchret from %1 to label %catchret.dest
32
33 catchret.dest: ; preds = %catch.1
34 ret void
35
36 invoke.cont: ; preds = %entry
37 %4 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call)
38 call void @objc_release(i8* %4)
39 ret void
40 }
41
42 declare i8* @"\01?f@@YAPAUobjc_object@@XZ"()
43
44 declare i32 @__CxxFrameHandler3(...)
45
46 declare dllimport i8* @objc_retainAutoreleasedReturnValue(i8*)
47
48 declare dllimport void @objc_release(i8*)
49
50 !clang.arc.retainAutoreleasedReturnValueMarker = !{!0}
51 !0 = !{!"movl\09%ebp, %ebp\09\09// marker for objc_retainAutoreleaseReturnValue"}
52
53 ; CHECK-LABEL: catch
54 ; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ]
55
56 ; CHECK-LABEL: catch.1
57 ; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ]
58
59 ; CHECK-LABEL: invoke.cont
60 ; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""(){{$}}