EscapeEnumerator.cpp 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. //===- EscapeEnumerator.cpp -----------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Defines a helper class that enumerates all possible exits from a function,
  10. // including exception handling.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/Transforms/Utils/EscapeEnumerator.h"
  14. #include "llvm/Analysis/EHPersonalities.h"
  15. #include "llvm/Transforms/Utils/Local.h"
  16. #include "llvm/IR/CallSite.h"
  17. #include "llvm/IR/Module.h"
  18. using namespace llvm;
  19. static FunctionCallee getDefaultPersonalityFn(Module *M) {
  20. LLVMContext &C = M->getContext();
  21. Triple T(M->getTargetTriple());
  22. EHPersonality Pers = getDefaultEHPersonality(T);
  23. return M->getOrInsertFunction(getEHPersonalityName(Pers),
  24. FunctionType::get(Type::getInt32Ty(C), true));
  25. }
  26. IRBuilder<> *EscapeEnumerator::Next() {
  27. if (Done)
  28. return nullptr;
  29. // Find all 'return', 'resume', and 'unwind' instructions.
  30. while (StateBB != StateE) {
  31. BasicBlock *CurBB = &*StateBB++;
  32. // Branches and invokes do not escape, only unwind, resume, and return
  33. // do.
  34. Instruction *TI = CurBB->getTerminator();
  35. if (!isa<ReturnInst>(TI) && !isa<ResumeInst>(TI))
  36. continue;
  37. Builder.SetInsertPoint(TI);
  38. return &Builder;
  39. }
  40. Done = true;
  41. if (!HandleExceptions)
  42. return nullptr;
  43. if (F.doesNotThrow())
  44. return nullptr;
  45. // Find all 'call' instructions that may throw.
  46. SmallVector<Instruction *, 16> Calls;
  47. for (BasicBlock &BB : F)
  48. for (Instruction &II : BB)
  49. if (CallInst *CI = dyn_cast<CallInst>(&II))
  50. if (!CI->doesNotThrow())
  51. Calls.push_back(CI);
  52. if (Calls.empty())
  53. return nullptr;
  54. // Create a cleanup block.
  55. LLVMContext &C = F.getContext();
  56. BasicBlock *CleanupBB = BasicBlock::Create(C, CleanupBBName, &F);
  57. Type *ExnTy = StructType::get(Type::getInt8PtrTy(C), Type::getInt32Ty(C));
  58. if (!F.hasPersonalityFn()) {
  59. FunctionCallee PersFn = getDefaultPersonalityFn(F.getParent());
  60. F.setPersonalityFn(cast<Constant>(PersFn.getCallee()));
  61. }
  62. if (isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) {
  63. report_fatal_error("Scoped EH not supported");
  64. }
  65. LandingPadInst *LPad =
  66. LandingPadInst::Create(ExnTy, 1, "cleanup.lpad", CleanupBB);
  67. LPad->setCleanup(true);
  68. ResumeInst *RI = ResumeInst::Create(LPad, CleanupBB);
  69. // Transform the 'call' instructions into 'invoke's branching to the
  70. // cleanup block. Go in reverse order to make prettier BB names.
  71. SmallVector<Value *, 16> Args;
  72. for (unsigned I = Calls.size(); I != 0;) {
  73. CallInst *CI = cast<CallInst>(Calls[--I]);
  74. changeToInvokeAndSplitBasicBlock(CI, CleanupBB);
  75. }
  76. Builder.SetInsertPoint(RI);
  77. return &Builder;
  78. }