/// AddLandingPadInfo - Extract the exception handling information from the
/// landingpad instruction and add them to the specified machine module info.
void llvm::AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI,
                             MachineBasicBlock *MBB) {
    if (const auto *PF = dyn_cast<Function>(
                             I.getParent()->getParent()->getPersonalityFn()->stripPointerCasts()))
        MMI.addPersonality(PF);

    if (I.isCleanup())
        MMI.addCleanup(MBB);

    // FIXME: New EH - Add the clauses in reverse order. This isn't 100% correct,
    //        but we need to do it this way because of how the DWARF EH emitter
    //        processes the clauses.
    for (unsigned i = I.getNumClauses(); i != 0; --i) {
        Value *Val = I.getClause(i - 1);
        if (I.isCatch(i - 1)) {
            MMI.addCatchTypeInfo(MBB,
                                 dyn_cast<GlobalValue>(Val->stripPointerCasts()));
        } else {
            // Add filters in a list.
            Constant *CVal = cast<Constant>(Val);
            SmallVector<const GlobalValue*, 4> FilterList;
            for (User::op_iterator
                    II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II)
                FilterList.push_back(cast<GlobalValue>((*II)->stripPointerCasts()));

            MMI.addFilterTypeInfo(MBB, FilterList);
        }
    }
}
/// setupFunctionContext - Allocate the function context on the stack and fill
/// it with all of the data that we know at this point.
Value *SjLjEHPrepare::setupFunctionContext(Function &F,
                                           ArrayRef<LandingPadInst *> LPads) {
  BasicBlock *EntryBB = F.begin();

  // Create an alloca for the incoming jump buffer ptr and the new jump buffer
  // that needs to be restored on all exits from the function. This is an alloca
  // because the value needs to be added to the global context list.
  const TargetLowering *TLI = TM->getTargetLowering();
  unsigned Align =
      TLI->getDataLayout()->getPrefTypeAlignment(FunctionContextTy);
  FuncCtx = new AllocaInst(FunctionContextTy, nullptr, Align, "fn_context",
                           EntryBB->begin());

  // Fill in the function context structure.
  for (unsigned I = 0, E = LPads.size(); I != E; ++I) {
    LandingPadInst *LPI = LPads[I];
    IRBuilder<> Builder(LPI->getParent()->getFirstInsertionPt());

    // Reference the __data field.
    Value *FCData = Builder.CreateConstGEP2_32(FuncCtx, 0, 2, "__data");

    // The exception values come back in context->__data[0].
    Value *ExceptionAddr =
        Builder.CreateConstGEP2_32(FCData, 0, 0, "exception_gep");
    Value *ExnVal = Builder.CreateLoad(ExceptionAddr, true, "exn_val");
    ExnVal = Builder.CreateIntToPtr(ExnVal, Builder.getInt8PtrTy());

    Value *SelectorAddr =
        Builder.CreateConstGEP2_32(FCData, 0, 1, "exn_selector_gep");
    Value *SelVal = Builder.CreateLoad(SelectorAddr, true, "exn_selector_val");

    substituteLPadValues(LPI, ExnVal, SelVal);
  }

  // Personality function
  IRBuilder<> Builder(EntryBB->getTerminator());
  if (!PersonalityFn)
    PersonalityFn = LPads[0]->getPersonalityFn();
  Value *PersonalityFieldPtr =
      Builder.CreateConstGEP2_32(FuncCtx, 0, 3, "pers_fn_gep");
  Builder.CreateStore(
      Builder.CreateBitCast(PersonalityFn, Builder.getInt8PtrTy()),
      PersonalityFieldPtr, /*isVolatile=*/true);

  // LSDA address
  Value *LSDA = Builder.CreateCall(LSDAAddrFn, "lsda_addr");
  Value *LSDAFieldPtr = Builder.CreateConstGEP2_32(FuncCtx, 0, 4, "lsda_gep");
  Builder.CreateStore(LSDA, LSDAFieldPtr, /*isVolatile=*/true);

  return FuncCtx;
}
Beispiel #3
0
/// setupFunctionContext - Allocate the function context on the stack and fill
/// it with all of the data that we know at this point.
Value *SjLjEHPass::
setupFunctionContext(Function &F, ArrayRef<LandingPadInst*> LPads) {
  BasicBlock *EntryBB = F.begin();

  // Create an alloca for the incoming jump buffer ptr and the new jump buffer
  // that needs to be restored on all exits from the function. This is an alloca
  // because the value needs to be added to the global context list.
  unsigned Align =
    TLI->getTargetData()->getPrefTypeAlignment(FunctionContextTy);
  FuncCtx =
    new AllocaInst(FunctionContextTy, 0, Align, "fn_context", EntryBB->begin());

  // Fill in the function context structure.
  Type *Int32Ty = Type::getInt32Ty(F.getContext());
  Value *Zero = ConstantInt::get(Int32Ty, 0);
  Value *One = ConstantInt::get(Int32Ty, 1);
  Value *Two = ConstantInt::get(Int32Ty, 2);
  Value *Three = ConstantInt::get(Int32Ty, 3);
  Value *Four = ConstantInt::get(Int32Ty, 4);

  Value *Idxs[2] = { Zero, 0 };

  for (unsigned I = 0, E = LPads.size(); I != E; ++I) {
    LandingPadInst *LPI = LPads[I];
    IRBuilder<> Builder(LPI->getParent()->getFirstInsertionPt());

    // Reference the __data field.
    Idxs[1] = Two;
    Value *FCData = Builder.CreateGEP(FuncCtx, Idxs, "__data");

    // The exception values come back in context->__data[0].
    Idxs[1] = Zero;
    Value *ExceptionAddr = Builder.CreateGEP(FCData, Idxs, "exception_gep");
    Value *ExnVal = Builder.CreateLoad(ExceptionAddr, true, "exn_val");
    ExnVal = Builder.CreateIntToPtr(ExnVal, Type::getInt8PtrTy(F.getContext()));

    Idxs[1] = One;
    Value *SelectorAddr = Builder.CreateGEP(FCData, Idxs, "exn_selector_gep");
    Value *SelVal = Builder.CreateLoad(SelectorAddr, true, "exn_selector_val");

    substituteLPadValues(LPI, ExnVal, SelVal);
  }

  // Personality function
  Idxs[1] = Three;
  if (!PersonalityFn)
    PersonalityFn = LPads[0]->getPersonalityFn();
  Value *PersonalityFieldPtr =
    GetElementPtrInst::Create(FuncCtx, Idxs, "pers_fn_gep",
                              EntryBB->getTerminator());
  new StoreInst(PersonalityFn, PersonalityFieldPtr, true,
                EntryBB->getTerminator());

  // LSDA address
  Value *LSDA = CallInst::Create(LSDAAddrFn, "lsda_addr",
                                 EntryBB->getTerminator());
  Idxs[1] = Four;
  Value *LSDAFieldPtr = GetElementPtrInst::Create(FuncCtx, Idxs, "lsda_gep",
                                                  EntryBB->getTerminator());
  new StoreInst(LSDA, LSDAFieldPtr, true, EntryBB->getTerminator());

  return FuncCtx;
}