llvm.org GIT mirror llvm / 890c166
[CodeGen] Force emission of personality directive if explicitly specified Summary: Before this change, personality directives were not emitted if there was no invoke left in the function (of course until recently this also meant that we couldn't know what the personality actually was). This patch forces personality directives to still be emitted, unless it is known to be a noop in the absence of invokes, or the user explicitly specified `nounwind` (and not `uwtable`) on the function. Reviewers: majnemer, rnk Subscribers: rnk, llvm-commits Differential Revision: http://reviews.llvm.org/D10884 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242185 91177308-0d34-0410-b5e6-96231b3b80d8 Keno Fischer 5 years ago
8 changed file(s) with 81 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
205205 llvm_unreachable("invalid enum");
206206 }
207207
208 /// \brief Return true if this personality may be safely removed if there
209 /// are no invoke instructions remaining in the current function.
210 inline bool isNoOpWithoutInvoke(EHPersonality Pers) {
211 switch (Pers) {
212 case EHPersonality::Unknown:
213 return false;
214 // All known personalities currently have this behavior
215 default: return true;
216 }
217 llvm_unreachable("invalid enum");
218 }
219
208220 bool canSimplifyInvokeNoUnwind(const Function *F);
209221
210222 } // end namespace llvm
319319 /// information.
320320 void addPersonality(MachineBasicBlock *LandingPad,
321321 const Function *Personality);
322 void addPersonality(const Function *Personality);
322323
323324 void addWinEHState(MachineBasicBlock *LandingPad, int State);
324325
6868 ///
6969 void ARMException::endFunction(const MachineFunction *MF) {
7070 ARMTargetStreamer &ATS = getTargetStreamer();
71 const Function *F = MF->getFunction();
72 const Function *Per = nullptr;
73 if (F->hasPersonalityFn())
74 Per = dyn_cast(F->getPersonalityFn()->stripPointerCasts());
75 assert(!MMI->getPersonality() || Per == MMI->getPersonality());
76 bool forceEmitPersonality =
77 F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
78 F->needsUnwindTableEntry();
79 bool shouldEmitPersonality = forceEmitPersonality ||
80 !MMI->getLandingPads().empty();
7181 if (!Asm->MF->getFunction()->needsUnwindTableEntry() &&
72 MMI->getLandingPads().empty())
82 !shouldEmitPersonality)
7383 ATS.emitCantUnwind();
74 else {
75 if (!MMI->getLandingPads().empty()) {
76 // Emit references to personality.
77 if (const Function *Personality = MMI->getPersonality()) {
78 MCSymbol *PerSym = Asm->getSymbol(Personality);
79 Asm->OutStreamer->EmitSymbolAttribute(PerSym, MCSA_Global);
80 ATS.emitPersonality(PerSym);
81 }
84 else if (shouldEmitPersonality) {
85 // Emit references to personality.
86 if (Per) {
87 MCSymbol *PerSym = Asm->getSymbol(Per);
88 Asm->OutStreamer->EmitSymbolAttribute(PerSym, MCSA_Global);
89 ATS.emitPersonality(PerSym);
90 }
8291
83 // Emit .handlerdata directive.
84 ATS.emitHandlerData();
92 // Emit .handlerdata directive.
93 ATS.emitHandlerData();
8594
86 // Emit actual exception table
87 emitExceptionTable();
88 }
95 // Emit actual exception table
96 emitExceptionTable();
8997 }
9098
9199 if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
8888
8989 void DwarfCFIException::beginFunction(const MachineFunction *MF) {
9090 shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
91 const Function *F = MF->getFunction();
9192
9293 // If any landing pads survive, we need an EH table.
9394 bool hasLandingPads = !MMI->getLandingPads().empty();
103104
104105 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
105106 unsigned PerEncoding = TLOF.getPersonalityEncoding();
106 const Function *Per = MMI->getPersonality();
107 const Function *Per = nullptr;
108 if (F->hasPersonalityFn())
109 Per = dyn_cast(F->getPersonalityFn()->stripPointerCasts());
110 assert(!MMI->getPersonality() || Per == MMI->getPersonality());
107111
108 shouldEmitPersonality = hasLandingPads &&
109 PerEncoding != dwarf::DW_EH_PE_omit && Per;
112 // Emit a personality function even when there are no landing pads
113 bool forceEmitPersonality =
114 // ...if a personality function is explicitly specified
115 F->hasPersonalityFn() &&
116 // ... and it's not known to be a noop in the absence of invokes
117 !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
118 // ... and we're not explicitly asked not to emit it
119 F->needsUnwindTableEntry();
120
121 shouldEmitPersonality =
122 (forceEmitPersonality ||
123 (hasLandingPads && PerEncoding != dwarf::DW_EH_PE_omit)) &&
124 Per;
110125
111126 unsigned LSDAEncoding = TLOF.getLSDAEncoding();
112127 shouldEmitLSDA = shouldEmitPersonality &&
121136 // Indicate personality routine, if any.
122137 if (!shouldEmitPersonality)
123138 return;
139
140 // If we are forced to emit this personality, make sure to record
141 // it because it might not appear in any landingpad
142 if (forceEmitPersonality)
143 MMI->addPersonality(Per);
124144
125145 const MCSymbol *Sym =
126146 TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
308308 // If some instruction between the previous try-range and the end of the
309309 // function may throw, create a call-site entry with no landing pad for the
310310 // region following the try-range.
311 if (SawPotentiallyThrowing && !IsSJLJ) {
311 if (SawPotentiallyThrowing && !IsSJLJ && LastLabel != nullptr) {
312312 CallSiteEntry Site = { LastLabel, nullptr, nullptr, 0 };
313313 CallSites.push_back(Site);
314314 }
7373 if (F->hasPersonalityFn())
7474 Per = dyn_cast(F->getPersonalityFn()->stripPointerCasts());
7575
76 shouldEmitPersonality = hasLandingPads &&
77 PerEncoding != dwarf::DW_EH_PE_omit && Per;
76 bool forceEmitPersonality =
77 F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
78 F->needsUnwindTableEntry();
79
80 shouldEmitPersonality = forceEmitPersonality || (hasLandingPads &&
81 PerEncoding != dwarf::DW_EH_PE_omit && Per);
7882
7983 unsigned LSDAEncoding = TLOF.getLSDAEncoding();
8084 shouldEmitLSDA = shouldEmitPersonality &&
319319 const Function *Personality) {
320320 LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
321321 LP.Personality = Personality;
322
322 addPersonality(Personality);
323 }
324
325 void MachineModuleInfo::addPersonality(const Function *Personality) {
323326 for (unsigned i = 0; i < Personalities.size(); ++i)
324327 if (Personalities[i] == Personality)
325328 return;
0 ; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s
1 ; Test that we emit functions with explicitly specified personality,
2 ; even if no landing pads are left.
3
4 declare i32 @__my_personality_v0(...)
5 declare void @might_throw()
6
7 define i32 @foo() personality i32 (...)* @__my_personality_v0 {
8 ; CHECK: .cfi_personality 3, __my_personality_v0
9 call void @might_throw()
10 ret i32 0
11 }