|
18 | 18 | #include "llvm/Analysis/DomTreeUpdater.h"
|
19 | 19 | #include "llvm/Analysis/TargetTransformInfo.h"
|
20 | 20 | #include "llvm/CodeGen/RuntimeLibcalls.h"
|
21 |
| -#include "llvm/CodeGen/StackProtector.h" |
22 | 21 | #include "llvm/CodeGen/TargetLowering.h"
|
23 | 22 | #include "llvm/CodeGen/TargetPassConfig.h"
|
24 | 23 | #include "llvm/CodeGen/TargetSubtargetInfo.h"
|
|
29 | 28 | #include "llvm/IR/Dominators.h"
|
30 | 29 | #include "llvm/IR/EHPersonalities.h"
|
31 | 30 | #include "llvm/IR/Function.h"
|
32 |
| -#include "llvm/IR/IRBuilder.h" |
33 | 31 | #include "llvm/IR/Instructions.h"
|
34 | 32 | #include "llvm/IR/Module.h"
|
35 | 33 | #include "llvm/IR/Type.h"
|
|
39 | 37 | #include "llvm/Target/TargetMachine.h"
|
40 | 38 | #include "llvm/TargetParser/Triple.h"
|
41 | 39 | #include "llvm/Transforms/Utils/Local.h"
|
42 |
| -#include "llvm/Transforms/Utils/BasicBlockUtils.h" |
43 | 40 | #include <cstddef>
|
44 | 41 |
|
45 | 42 | using namespace llvm;
|
@@ -169,136 +166,7 @@ size_t DwarfEHPrepare::pruneUnreachableResumes(
|
169 | 166 | return ResumesLeft;
|
170 | 167 | }
|
171 | 168 |
|
172 |
| -/// If a landingpad block doesn't already have a cleanup case, add one |
173 |
| -/// that feeds directly into a resume instruction. |
174 |
| -static void addCleanupResumeToLandingPad(BasicBlock &BB, DomTreeUpdater *DTU) { |
175 |
| - LandingPadInst *LP = BB.getLandingPadInst(); |
176 |
| - if (LP->isCleanup()) |
177 |
| - return; |
178 |
| - |
179 |
| - // There will usually be code testing for the other kinds of exception |
180 |
| - // immediately after the landingpad. Working out the far end of that chain is |
181 |
| - // tricky, so put our test for the new cleanup case (i.e. selector == 0) at |
182 |
| - // the beginning. |
183 |
| - BasicBlock *ContBB = SplitBlock(&BB, LP->getNextNode(), DTU); |
184 |
| - BB.getTerminator()->eraseFromParent(); |
185 |
| - |
186 |
| - LP->setCleanup(true); |
187 |
| - IRBuilder<> B(&BB); |
188 |
| - Value *Selector = B.CreateExtractValue(LP, 1); |
189 |
| - Value *Cmp = B.CreateICmpEQ(Selector, ConstantInt::get(Selector->getType(), 0)); |
190 |
| - |
191 |
| - Function *F = BB.getParent(); |
192 |
| - LLVMContext &Ctx = F->getContext(); |
193 |
| - BasicBlock *ResumeBB = BasicBlock::Create(Ctx, "resume", F); |
194 |
| - ResumeInst::Create(LP, ResumeBB); |
195 |
| - |
196 |
| - B.CreateCondBr(Cmp, ResumeBB, ContBB); |
197 |
| - if (DTU) { |
198 |
| - SmallVector<DominatorTree::UpdateType> Updates; |
199 |
| - Updates.push_back({DominatorTree::Insert, &BB, ResumeBB}); |
200 |
| - DTU->applyUpdates(Updates); |
201 |
| - } |
202 |
| -} |
203 |
| - |
204 |
| -/// Create a basic block that has a `landingpad` instruction feeding |
205 |
| -/// directly into a `resume`. Will be set to the unwind destination of a new |
206 |
| -/// invoke. |
207 |
| -static BasicBlock *createCleanupResumeBB(Function &F, Type *LandingPadTy) { |
208 |
| - LLVMContext &Ctx = F.getContext(); |
209 |
| - BasicBlock *BB = BasicBlock::Create(Ctx, "cleanup_resume", &F); |
210 |
| - IRBuilder<> B(BB); |
211 |
| - |
212 |
| - // If this is going to be the only landingpad in the function, synthesize the |
213 |
| - // standard type all ABIs use, which is essentially `{ ptr, i32 }`. |
214 |
| - if (!LandingPadTy) |
215 |
| - LandingPadTy = |
216 |
| - StructType::get(Type::getInt8PtrTy(Ctx), IntegerType::get(Ctx, 32)); |
217 |
| - |
218 |
| - LandingPadInst *Except = B.CreateLandingPad(LandingPadTy, 0); |
219 |
| - Except->setCleanup(true); |
220 |
| - B.CreateResume(Except); |
221 |
| - return BB; |
222 |
| -} |
223 |
| - |
224 |
| -/// Convert a call that might throw into an invoke that unwinds to the specified |
225 |
| -/// simple landingpad/resume block. |
226 |
| -static void changeCallToInvokeResume(CallInst &CI, BasicBlock *CleanupResumeBB, |
227 |
| - DomTreeUpdater *DTU) { |
228 |
| - BasicBlock *BB = CI.getParent(); |
229 |
| - BasicBlock *ContBB = SplitBlock(BB, &CI, DTU); |
230 |
| - BB->getTerminator()->eraseFromParent(); |
231 |
| - |
232 |
| - IRBuilder<> B(BB); |
233 |
| - SmallVector<Value *> Args(CI.args()); |
234 |
| - SmallVector<OperandBundleDef> Bundles; |
235 |
| - CI.getOperandBundlesAsDefs(Bundles); |
236 |
| - InvokeInst *NewCall = |
237 |
| - B.CreateInvoke(CI.getFunctionType(), CI.getCalledOperand(), ContBB, |
238 |
| - CleanupResumeBB, Args, Bundles, CI.getName()); |
239 |
| - NewCall->setAttributes(CI.getAttributes()); |
240 |
| - NewCall->setCallingConv(CI.getCallingConv()); |
241 |
| - NewCall->copyMetadata(CI); |
242 |
| - |
243 |
| - if (DTU) { |
244 |
| - SmallVector<DominatorTree::UpdateType> Updates; |
245 |
| - Updates.push_back({DominatorTree::Insert, BB, CleanupResumeBB}); |
246 |
| - DTU->applyUpdates(Updates); |
247 |
| - } |
248 |
| - CI.replaceAllUsesWith(NewCall); |
249 |
| - CI.eraseFromParent(); |
250 |
| -} |
251 |
| - |
252 |
| -/// Ensure that any call in this function that might throw has an associated |
253 |
| -/// cleanup/resume that the stack protector can instrument later. Existing |
254 |
| -/// invokes will get an added `cleanup` clause if needed, calls will be |
255 |
| -/// converted to an invoke with trivial unwind followup. |
256 |
| -static void addCleanupPathsForStackProtector(Function &F, DomTreeUpdater *DTU) { |
257 |
| - // First add cleanup -> resume paths to all existing landingpads, noting what |
258 |
| - // type landingpads in this function actually have along the way. |
259 |
| - Type *LandingPadTy = nullptr; |
260 |
| - for (Function::iterator FI = F.begin(); FI != F.end(); ++FI) { |
261 |
| - BasicBlock &BB = *FI; |
262 |
| - if (LandingPadInst *LP = BB.getLandingPadInst()) { |
263 |
| - // We can assume the type is broadly compatible with { ptr, i32 } since |
264 |
| - // other parts of this pass already try to extract values from it. |
265 |
| - LandingPadTy = LP->getType(); |
266 |
| - addCleanupResumeToLandingPad(BB, DTU); |
267 |
| - } |
268 |
| - } |
269 |
| - |
270 |
| - // Next convert any call that might throw into an invoke to a resume |
271 |
| - // instruction for later instrumentation. |
272 |
| - BasicBlock *CleanupResumeBB = nullptr; |
273 |
| - for (Function::iterator FI = F.begin(); FI != F.end(); ++FI) { |
274 |
| - BasicBlock &BB = *FI; |
275 |
| - for (Instruction &I : BB) { |
276 |
| - CallInst *CI = dyn_cast<CallInst>(&I); |
277 |
| - if (!CI || CI->doesNotThrow()) |
278 |
| - continue; |
279 |
| - |
280 |
| - // Tail calls cannot use our stack so no need to check whether it was |
281 |
| - // corrupted. |
282 |
| - if (CI->isTailCall()) |
283 |
| - continue; |
284 |
| - |
285 |
| - if (!CleanupResumeBB) |
286 |
| - CleanupResumeBB = createCleanupResumeBB(F, LandingPadTy); |
287 |
| - |
288 |
| - changeCallToInvokeResume(*CI, CleanupResumeBB, DTU); |
289 |
| - |
290 |
| - // This block has been split, start again on its continuation. |
291 |
| - break; |
292 |
| - } |
293 |
| - } |
294 |
| -} |
295 |
| - |
296 | 169 | bool DwarfEHPrepare::InsertUnwindResumeCalls() {
|
297 |
| - if (F.hasPersonalityFn() && |
298 |
| - !isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())) && |
299 |
| - StackProtector::requiresStackProtector(&F, nullptr)) |
300 |
| - addCleanupPathsForStackProtector(F, DTU); |
301 |
| - |
302 | 170 | SmallVector<ResumeInst *, 16> Resumes;
|
303 | 171 | SmallVector<LandingPadInst *, 16> CleanupLPads;
|
304 | 172 | if (F.doesNotThrow())
|
|
0 commit comments