Пример #1
0
bool LowerInvoke::insertCheapEHSupport(Function &F) {
  bool Changed = false;
  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
    if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) {
      SmallVector<Value*,16> CallArgs(II->op_begin(), II->op_end() - 3);
      // Insert a normal call instruction...
      CallInst *NewCall = CallInst::Create(II->getCalledValue(),
                                           CallArgs, "", II);
      NewCall->takeName(II);
      NewCall->setCallingConv(II->getCallingConv());
      NewCall->setAttributes(II->getAttributes());
      NewCall->setDebugLoc(II->getDebugLoc());
      II->replaceAllUsesWith(NewCall);

      // Insert an unconditional branch to the normal destination.
      BranchInst::Create(II->getNormalDest(), II);

      // Remove any PHI node entries from the exception destination.
      II->getUnwindDest()->removePredecessor(BB);

      // Remove the invoke instruction now.
      BB->getInstList().erase(II);

      ++NumInvokes; Changed = true;
    }
  return Changed;
}
Пример #2
0
// SimplifyFunction - Given information about callees, simplify the specified
// function if we have invokes to non-unwinding functions or code after calls to
// no-return functions.
bool PruneEH::SimplifyFunction(Function *F) {
  bool MadeChange = false;
  for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
    if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator()))
      if (II->doesNotThrow()) {
        SmallVector<Value*, 8> Args(II->op_begin(), II->op_end() - 3);
        // Insert a call instruction before the invoke.
        CallInst *Call = CallInst::Create(II->getCalledValue(),
                                          Args.begin(), Args.end(), "", II);
        Call->takeName(II);
        Call->setCallingConv(II->getCallingConv());
        Call->setAttributes(II->getAttributes());
        Call->setDebugLoc(II->getDebugLoc());

        // Anything that used the value produced by the invoke instruction
        // now uses the value produced by the call instruction.  Note that we
        // do this even for void functions and calls with no uses so that the
        // callgraph edge is updated.
        II->replaceAllUsesWith(Call);
        BasicBlock *UnwindBlock = II->getUnwindDest();
        UnwindBlock->removePredecessor(II->getParent());

        // Insert a branch to the normal destination right before the
        // invoke.
        BranchInst::Create(II->getNormalDest(), II);

        // Finally, delete the invoke instruction!
        BB->getInstList().pop_back();

        // If the unwind block is now dead, nuke it.
        if (pred_begin(UnwindBlock) == pred_end(UnwindBlock))
          DeleteBasicBlock(UnwindBlock);  // Delete the new BB.

        ++NumRemoved;
        MadeChange = true;
      }

    for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
      if (CallInst *CI = dyn_cast<CallInst>(I++))
        if (CI->doesNotReturn() && !isa<UnreachableInst>(I)) {
          // This call calls a function that cannot return.  Insert an
          // unreachable instruction after it and simplify the code.  Do this
          // by splitting the BB, adding the unreachable, then deleting the
          // new BB.
          BasicBlock *New = BB->splitBasicBlock(I);

          // Remove the uncond branch and add an unreachable.
          BB->getInstList().pop_back();
          new UnreachableInst(BB->getContext(), BB);

          DeleteBasicBlock(New);  // Delete the new BB.
          MadeChange = true;
          ++NumUnreach;
          break;
        }
  }

  return MadeChange;
}
// SimplifyFunction - Given information about callees, simplify the specified
// function if we have invokes to non-unwinding functions or code after calls to
// no-return functions.
bool PruneEH::SimplifyFunction(Function *F) {
  CallGraph &CG = getAnalysis<CallGraph>();
  bool MadeChange = false;
  for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
    if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator()))
      if (Function *F = II->getCalledFunction())
        if (DoesNotUnwind.count(CG[F])) {
          SmallVector<Value*, 8> Args(II->op_begin()+3, II->op_end());
          // Insert a call instruction before the invoke.
          CallInst *Call = new CallInst(II->getCalledValue(),
                                        &Args[0], Args.size(), "", II);
          Call->takeName(II);
          Call->setCallingConv(II->getCallingConv());

          // Anything that used the value produced by the invoke instruction
          // now uses the value produced by the call instruction.
          II->replaceAllUsesWith(Call);
          BasicBlock *UnwindBlock = II->getUnwindDest();
          UnwindBlock->removePredecessor(II->getParent());

          // Insert a branch to the normal destination right before the
          // invoke.
          new BranchInst(II->getNormalDest(), II);

          // Finally, delete the invoke instruction!
          BB->getInstList().pop_back();

          // If the unwind block is now dead, nuke it.
          if (pred_begin(UnwindBlock) == pred_end(UnwindBlock))
            DeleteBasicBlock(UnwindBlock);  // Delete the new BB.

          ++NumRemoved;
          MadeChange = true;
        }

    for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
      if (CallInst *CI = dyn_cast<CallInst>(I++))
        if (Function *Callee = CI->getCalledFunction())
          if (DoesNotReturn.count(CG[Callee]) && !isa<UnreachableInst>(I)) {
            // This call calls a function that cannot return.  Insert an
            // unreachable instruction after it and simplify the code.  Do this
            // by splitting the BB, adding the unreachable, then deleting the
            // new BB.
            BasicBlock *New = BB->splitBasicBlock(I);

            // Remove the uncond branch and add an unreachable.
            BB->getInstList().pop_back();
            new UnreachableInst(BB);

            DeleteBasicBlock(New);  // Delete the new BB.
            MadeChange = true;
            ++NumUnreach;
            break;
          }

  }
  return MadeChange;
}
  virtual bool runOnFunction(Function &F) {
    bool Modified = false;
    for (Function::iterator I = F.begin(); I != F.end(); I++) {
      BasicBlock *BB = I;

      for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
        // Note: taking BI++ out of the for statement is important. Since this
        // loop may delete the instruction at *BI, this will invalidate the
        // iterator. So we make sure the iterator is incremented right from
        // the start and it already points to the next instruction. This way,
        // removing I from the basic block is harmless.
        Instruction &I = *BI++;

        // These nested conditions match a specific instruction pattern. We're
        // looking for a load whose address is a GEP constant expression.
        if (LoadInst *Load = dyn_cast<LoadInst>(&I)) {
          if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Load->getOperand(0))) {
            if (GEPOperator *GEP = dyn_cast<GEPOperator>(CE)) {
              Value *Ptr = GEP->getPointerOperand();

              // Only look for accesses to threadIdx with the expected amount of
              // GEP indices (essentially struct access to threadIdx.<member>.
              if (Ptr->getName() != "threadIdx" || GEP->getNumIndices() != 2) {
                continue;
              }

              // struct access as a GEP has two indices; read the LLVM
              // documentation on GEPs if this doesn't make sense.
              if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2))) {
                // Choose a function based on the index.
                uint64_t DimIndex = CI->getZExtValue();
                Function *TargetFunc;
                if (DimIndex == 0) {
                  TargetFunc = TidxRef;
                } else if (DimIndex == 1) {
                  TargetFunc = TidyRef;
                } else if (DimIndex == 2) {
                  TargetFunc = TidzRef;
                } else {
                  report_fatal_error("Invalid index for threadIdx access");
                }

                // Create a call instruction to the appropriate _tid* function
                // right before the load and replace the load by it.
                CallInst *TidFuncCall = CallInst::Create(TargetFunc, "", Load);
                TidFuncCall->takeName(Load);
                Load->replaceAllUsesWith(TidFuncCall);
                Load->eraseFromParent();
                Modified = true;
              }
            }
          }
        }
      }
    }

    return Modified;
  }
Value *WebAssemblyLowerEmscriptenEHSjLj::wrapInvoke(CallOrInvoke *CI) {
  LLVMContext &C = CI->getModule()->getContext();

  // If we are calling a function that is noreturn, we must remove that
  // attribute. The code we insert here does expect it to return, after we
  // catch the exception.
  if (CI->doesNotReturn()) {
    if (auto *F = dyn_cast<Function>(CI->getCalledValue()))
      F->removeFnAttr(Attribute::NoReturn);
    CI->removeAttribute(AttributeList::FunctionIndex, Attribute::NoReturn);
  }

  IRBuilder<> IRB(C);
  IRB.SetInsertPoint(CI);

  // Pre-invoke
  // __THREW__ = 0;
  IRB.CreateStore(IRB.getInt32(0), ThrewGV);

  // Invoke function wrapper in JavaScript
  SmallVector<Value *, 16> Args;
  // Put the pointer to the callee as first argument, so it can be called
  // within the invoke wrapper later
  Args.push_back(CI->getCalledValue());
  Args.append(CI->arg_begin(), CI->arg_end());
  CallInst *NewCall = IRB.CreateCall(getInvokeWrapper(CI), Args);
  NewCall->takeName(CI);
  NewCall->setCallingConv(CI->getCallingConv());
  NewCall->setDebugLoc(CI->getDebugLoc());

  // Because we added the pointer to the callee as first argument, all
  // argument attribute indices have to be incremented by one.
  SmallVector<AttributeSet, 8> ArgAttributes;
  const AttributeList &InvokeAL = CI->getAttributes();

  // No attributes for the callee pointer.
  ArgAttributes.push_back(AttributeSet());
  // Copy the argument attributes from the original
  for (unsigned i = 0, e = CI->getNumArgOperands(); i < e; ++i)
    ArgAttributes.push_back(InvokeAL.getParamAttributes(i));

  // Reconstruct the AttributesList based on the vector we constructed.
  AttributeList NewCallAL =
      AttributeList::get(C, InvokeAL.getFnAttributes(),
                         InvokeAL.getRetAttributes(), ArgAttributes);
  NewCall->setAttributes(NewCallAL);

  CI->replaceAllUsesWith(NewCall);

  // Post-invoke
  // %__THREW__.val = __THREW__; __THREW__ = 0;
  Value *Threw = IRB.CreateLoad(ThrewGV, ThrewGV->getName() + ".val");
  IRB.CreateStore(IRB.getInt32(0), ThrewGV);
  return Threw;
}
Пример #6
0
/// rewriteExpensiveInvoke - Insert code and hack the function to replace the
/// specified invoke instruction with a call.
void LowerInvoke::rewriteExpensiveInvoke(InvokeInst *II, unsigned InvokeNo,
                                         AllocaInst *InvokeNum,
                                         AllocaInst *StackPtr,
                                         SwitchInst *CatchSwitch) {
  ConstantInt *InvokeNoC = ConstantInt::get(Type::getInt32Ty(II->getContext()),
                                            InvokeNo);

  // If the unwind edge has phi nodes, split the edge.
  if (isa<PHINode>(II->getUnwindDest()->begin())) {
    SplitCriticalEdge(II, 1, this);

    // If there are any phi nodes left, they must have a single predecessor.
    while (PHINode *PN = dyn_cast<PHINode>(II->getUnwindDest()->begin())) {
      PN->replaceAllUsesWith(PN->getIncomingValue(0));
      PN->eraseFromParent();
    }
  }

  // Insert a store of the invoke num before the invoke and store zero into the
  // location afterward.
  new StoreInst(InvokeNoC, InvokeNum, true, II);  // volatile
  
  // Insert a store of the stack ptr before the invoke, so we can restore it
  // later in the exception case.
  CallInst* StackSaveRet = CallInst::Create(StackSaveFn, "ssret", II);
  new StoreInst(StackSaveRet, StackPtr, true, II); // volatile

  BasicBlock::iterator NI = II->getNormalDest()->getFirstInsertionPt();
  // nonvolatile.
  new StoreInst(Constant::getNullValue(Type::getInt32Ty(II->getContext())), 
                InvokeNum, false, NI);

  Instruction* StackPtrLoad =
    new LoadInst(StackPtr, "stackptr.restore", true,
                 II->getUnwindDest()->getFirstInsertionPt());
  CallInst::Create(StackRestoreFn, StackPtrLoad, "")->insertAfter(StackPtrLoad);
    
  // Add a switch case to our unwind block.
  CatchSwitch->addCase(InvokeNoC, II->getUnwindDest());

  // Insert a normal call instruction.
  SmallVector<Value*,16> CallArgs(II->op_begin(), II->op_end() - 3);
  CallInst *NewCall = CallInst::Create(II->getCalledValue(),
                                       CallArgs, "", II);
  NewCall->takeName(II);
  NewCall->setCallingConv(II->getCallingConv());
  NewCall->setAttributes(II->getAttributes());
  NewCall->setDebugLoc(II->getDebugLoc());
  II->replaceAllUsesWith(NewCall);

  // Replace the invoke with an uncond branch.
  BranchInst::Create(II->getNormalDest(), NewCall->getParent());
  II->eraseFromParent();
}
Пример #7
0
/// changeToCall - Convert the specified invoke into a normal call.
static void changeToCall(InvokeInst *II) {
  SmallVector<Value*, 8> Args(II->op_begin(), II->op_end() - 3);
  CallInst *NewCall = CallInst::Create(II->getCalledValue(), Args, "", II);
  NewCall->takeName(II);
  NewCall->setCallingConv(II->getCallingConv());
  NewCall->setAttributes(II->getAttributes());
  NewCall->setDebugLoc(II->getDebugLoc());
  II->replaceAllUsesWith(NewCall);

  // Follow the call by a branch to the normal destination.
  BranchInst::Create(II->getNormalDest(), II);

  // Update PHI nodes in the unwind destination
  II->getUnwindDest()->removePredecessor(II->getParent());
  II->eraseFromParent();
}
Пример #8
0
/// ChangeToCall - Convert the specified invoke into a normal call.
static void ChangeToCall(InvokeInst *II) {
    BasicBlock *BB = II->getParent();
    SmallVector<Value*, 8> Args(II->op_begin()+3, II->op_end());
    CallInst *NewCall = CallInst::Create(II->getCalledValue(), Args.begin(),
                                         Args.end(), "", II);
    NewCall->takeName(II);
    NewCall->setCallingConv(II->getCallingConv());
    NewCall->setParamAttrs(II->getParamAttrs());
    II->replaceAllUsesWith(NewCall);

    // Follow the call by a branch to the normal destination.
    BranchInst::Create(II->getNormalDest(), II);

    // Update PHI nodes in the unwind destination
    II->getUnwindDest()->removePredecessor(BB);
    BB->getInstList().erase(II);
}
static void convertInvokeToCall(InvokeInst *Invoke) {
  SmallVector<Value*, 16> CallArgs(Invoke->op_begin(), Invoke->op_end() - 3);
  // Insert a normal call instruction.
  CallInst *NewCall = CallInst::Create(Invoke->getCalledValue(),
                                       CallArgs, "", Invoke);
  CopyDebug(NewCall, Invoke);
  NewCall->takeName(Invoke);
  NewCall->setCallingConv(Invoke->getCallingConv());
  NewCall->setAttributes(Invoke->getAttributes());
  Invoke->replaceAllUsesWith(NewCall);

  // Insert an unconditional branch to the normal destination.
  BranchInst::Create(Invoke->getNormalDest(), Invoke);
  // Remove any PHI node entries from the exception destination.
  Invoke->getUnwindDest()->removePredecessor(Invoke->getParent());
  Invoke->eraseFromParent();
}
Пример #10
0
bool LowerInvoke::insertCheapEHSupport(Function &F) {
  bool Changed = false;
  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
    if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) {
      std::vector<Value*> CallArgs(II->op_begin()+3, II->op_end());
      // Insert a normal call instruction...
      CallInst *NewCall = CallInst::Create(II->getCalledValue(),
                                           CallArgs.begin(), CallArgs.end(), "",II);
      NewCall->takeName(II);
      NewCall->setCallingConv(II->getCallingConv());
      NewCall->setAttributes(II->getAttributes());
      II->replaceAllUsesWith(NewCall);

      // Insert an unconditional branch to the normal destination.
      BranchInst::Create(II->getNormalDest(), II);

      // Remove any PHI node entries from the exception destination.
      II->getUnwindDest()->removePredecessor(BB);

      // Remove the invoke instruction now.
      BB->getInstList().erase(II);

      ++NumInvokes; Changed = true;
    } else if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) {
      // Insert a new call to write(2, AbortMessage, AbortMessageLength);
      writeAbortMessage(UI);

      // Insert a call to abort()
      CallInst::Create(AbortFn, "", UI)->setTailCall();

      // Insert a return instruction.  This really should be a "barrier", as it
      // is unreachable.
      ReturnInst::Create(F.getContext(),
                         F.getReturnType() == Type::getVoidTy(F.getContext()) ?
                          0 : Constant::getNullValue(F.getReturnType()), UI);

      // Remove the unwind instruction now.
      BB->getInstList().erase(UI);

      ++NumUnwinds; Changed = true;
    }
  return Changed;
}
Пример #11
0
/// rewriteExpensiveInvoke - Insert code and hack the function to replace the
/// specified invoke instruction with a call.
void LowerInvoke::rewriteExpensiveInvoke(InvokeInst *II, unsigned InvokeNo,
                                         AllocaInst *InvokeNum,
                                         SwitchInst *CatchSwitch) {
  ConstantInt *InvokeNoC = ConstantInt::get(Type::getInt32Ty(II->getContext()),
                                            InvokeNo);

  // If the unwind edge has phi nodes, split the edge.
  if (isa<PHINode>(II->getUnwindDest()->begin())) {
    SplitCriticalEdge(II, 1, this);

    // If there are any phi nodes left, they must have a single predecessor.
    while (PHINode *PN = dyn_cast<PHINode>(II->getUnwindDest()->begin())) {
      PN->replaceAllUsesWith(PN->getIncomingValue(0));
      PN->eraseFromParent();
    }
  }

  // Insert a store of the invoke num before the invoke and store zero into the
  // location afterward.
  new StoreInst(InvokeNoC, InvokeNum, true, II);  // volatile

  BasicBlock::iterator NI = II->getNormalDest()->getFirstNonPHI();
  // nonvolatile.
  new StoreInst(Constant::getNullValue(Type::getInt32Ty(II->getContext())), 
                InvokeNum, false, NI);

  // Add a switch case to our unwind block.
  CatchSwitch->addCase(InvokeNoC, II->getUnwindDest());

  // Insert a normal call instruction.
  std::vector<Value*> CallArgs(II->op_begin()+3, II->op_end());
  CallInst *NewCall = CallInst::Create(II->getCalledValue(),
                                       CallArgs.begin(), CallArgs.end(), "",
                                       II);
  NewCall->takeName(II);
  NewCall->setCallingConv(II->getCallingConv());
  NewCall->setAttributes(II->getAttributes());
  II->replaceAllUsesWith(NewCall);

  // Replace the invoke with an uncond branch.
  BranchInst::Create(II->getNormalDest(), NewCall->getParent());
  II->eraseFromParent();
}
void RewritePNaClLibraryCalls::rewriteSetjmpCall(CallInst *Call) {
  // Find the intrinsic function.
  Function *NaClSetjmpFunc = findSetjmpIntrinsic();
  // Cast the jmp_buf argument to the type NaClSetjmpCall expects.
  Type *PtrTy = NaClSetjmpFunc->getFunctionType()->getParamType(0);
  BitCastInst *JmpBufCast = new BitCastInst(Call->getArgOperand(0), PtrTy,
                                            "jmp_buf_i8", Call);
  const DebugLoc &DLoc = Call->getDebugLoc();
  JmpBufCast->setDebugLoc(DLoc);

  // Emit the updated call.
  Value *Args[] = { JmpBufCast };
  CallInst *NaClSetjmpCall = CallInst::Create(NaClSetjmpFunc, Args, "", Call);
  NaClSetjmpCall->setDebugLoc(DLoc);
  NaClSetjmpCall->takeName(Call);

  // Replace the original call.
  Call->replaceAllUsesWith(NaClSetjmpCall);
  Call->eraseFromParent();
}
bool LowerEmExceptions::runOnModule(Module &M) {
  TheModule = &M;

  // Add functions

  Type *i32 = Type::getInt32Ty(M.getContext());
  Type *i8 = Type::getInt8Ty(M.getContext());
  Type *i1 = Type::getInt1Ty(M.getContext());
  Type *i8P = i8->getPointerTo();
  Type *Void = Type::getVoidTy(M.getContext());

  if (!(GetHigh = TheModule->getFunction("getHigh32"))) {
    FunctionType *GetHighFunc = FunctionType::get(i32, false);
    GetHigh = Function::Create(GetHighFunc, GlobalValue::ExternalLinkage,
                               "getHigh32", TheModule);
  }

  if (!(PreInvoke = TheModule->getFunction("emscripten_preinvoke"))) {
    FunctionType *VoidFunc = FunctionType::get(Void, false);
    PreInvoke = Function::Create(VoidFunc, GlobalValue::ExternalLinkage, "emscripten_preinvoke", TheModule);
  }

  if (!(PostInvoke = TheModule->getFunction("emscripten_postinvoke"))) {
    FunctionType *IntFunc = FunctionType::get(i32, false);
    PostInvoke = Function::Create(IntFunc, GlobalValue::ExternalLinkage, "emscripten_postinvoke", TheModule);
  }

  FunctionType *LandingPadFunc = FunctionType::get(i8P, true);
  LandingPad = Function::Create(LandingPadFunc, GlobalValue::ExternalLinkage, "emscripten_landingpad", TheModule);

  FunctionType *ResumeFunc = FunctionType::get(Void, true);
  Resume = Function::Create(ResumeFunc, GlobalValue::ExternalLinkage, "emscripten_resume", TheModule);
  
  // Process

  bool HasWhitelist = Whitelist.size() > 0;
  std::string WhitelistChecker;
  if (HasWhitelist) WhitelistChecker = "," + Whitelist + ",";

  bool Changed = false;

  for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ) {
    Function *F = Iter++;

    std::vector<Instruction*> ToErase;
    std::set<LandingPadInst*> LandingPads;

    bool AllowExceptionsInFunc = !HasWhitelist || int(WhitelistChecker.find(F->getName())) > 0;

    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
      // check terminator for invokes
      if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) {
        LandingPads.insert(II->getLandingPadInst());

        bool NeedInvoke = AllowExceptionsInFunc && canThrow(II->getCalledValue());

        if (NeedInvoke) {
          // Insert a normal call instruction folded in between pre- and post-invoke
          CallInst::Create(PreInvoke, "", II);

          SmallVector<Value*,16> CallArgs(II->op_begin(), II->op_end() - 3);
          CallInst *NewCall = CallInst::Create(II->getCalledValue(),
                                               CallArgs, "", II);
          NewCall->takeName(II);
          NewCall->setCallingConv(II->getCallingConv());
          NewCall->setAttributes(II->getAttributes());
          NewCall->setDebugLoc(II->getDebugLoc());
          II->replaceAllUsesWith(NewCall);
          ToErase.push_back(II);

          CallInst *Post = CallInst::Create(PostInvoke, "", II);
          Instruction *Post1 = new TruncInst(Post, i1, "", II);

          // Insert a branch based on the postInvoke
          BranchInst::Create(II->getUnwindDest(), II->getNormalDest(), Post1, II);
        } else {
          // This can't throw, and we don't need this invoke, just replace it with a call+branch
          SmallVector<Value*,16> CallArgs(II->op_begin(), II->op_end() - 3);
          CallInst *NewCall = CallInst::Create(II->getCalledValue(),
                                               CallArgs, "", II);
          NewCall->takeName(II);
          NewCall->setCallingConv(II->getCallingConv());
          NewCall->setAttributes(II->getAttributes());
          NewCall->setDebugLoc(II->getDebugLoc());
          II->replaceAllUsesWith(NewCall);
          ToErase.push_back(II);

          BranchInst::Create(II->getNormalDest(), II);

          // Remove any PHI node entries from the exception destination.
          II->getUnwindDest()->removePredecessor(BB);
        }

        Changed = true;
      }
      // scan the body of the basic block for resumes
      for (BasicBlock::iterator Iter = BB->begin(), E = BB->end();
           Iter != E; ) {
        Instruction *I = Iter++;
        if (ResumeInst *R = dyn_cast<ResumeInst>(I)) {
          // split the input into legal values
          Value *Input = R->getValue();
          ExtractValueInst *Low = ExtractValueInst::Create(Input, 0, "", R);
          ExtractValueInst *High = ExtractValueInst::Create(Input, 1, "", R);

          // create a resume call
          SmallVector<Value*,2> CallArgs;
          CallArgs.push_back(Low);
          CallArgs.push_back(High);
          CallInst::Create(Resume, CallArgs, "", R);

          new UnreachableInst(TheModule->getContext(), R); // add a terminator to the block

          ToErase.push_back(R);
        }
      }
    }

    // Look for orphan landingpads, can occur in blocks with no predecesors
    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
      Instruction *I = BB->getFirstNonPHI();
      if (LandingPadInst *LP = dyn_cast<LandingPadInst>(I)) {
        LandingPads.insert(LP);
      }
    }

    // Handle all the landingpad for this function together, as multiple invokes may share a single lp
    for (std::set<LandingPadInst*>::iterator I = LandingPads.begin(); I != LandingPads.end(); I++) {
      // Replace the landingpad with a landingpad call to get the low part, and a getHigh for the high
      LandingPadInst *LP = *I;
      unsigned Num = LP->getNumClauses();
      SmallVector<Value*,16> NewLPArgs;
      NewLPArgs.push_back(LP->getPersonalityFn());
      for (unsigned i = 0; i < Num; i++) {
        Value *Arg = LP->getClause(i);
        // As a temporary workaround for the lack of aggregate varargs support
        // in the varargs lowering code, break out filter operands into their
        // component elements.
        if (LP->isFilter(i)) {
          ArrayType *ATy = cast<ArrayType>(Arg->getType());
          for (unsigned elem = 0, elemEnd = ATy->getNumElements(); elem != elemEnd; ++elem) {
            Instruction *EE = ExtractValueInst::Create(Arg, makeArrayRef(elem), "", LP);
            NewLPArgs.push_back(EE);
          }
        } else {
          NewLPArgs.push_back(Arg);
        }
      }
      NewLPArgs.push_back(LP->isCleanup() ? ConstantInt::getTrue(i1) : ConstantInt::getFalse(i1));
      CallInst *NewLP = CallInst::Create(LandingPad, NewLPArgs, "", LP);

      Instruction *High = CallInst::Create(GetHigh, "", LP);

      // New recreate an aggregate for them, which will be all simplified later (simplification cannot handle landingpad, hence all this)
      InsertValueInst *IVA = InsertValueInst::Create(UndefValue::get(LP->getType()), NewLP, 0, "", LP);
      InsertValueInst *IVB = InsertValueInst::Create(IVA, High, 1, "", LP);

      LP->replaceAllUsesWith(IVB);
      ToErase.push_back(LP);
    }

    // erase everything we no longer need in this function
    for (unsigned i = 0; i < ToErase.size(); i++) ToErase[i]->eraseFromParent();
  }

  return Changed;
}
// Convert the given call to use normalized argument/return types.
template <class T> static bool ConvertCall(T *Call, Pass *P) {
  // Don't try to change calls to intrinsics.
  if (isa<IntrinsicInst>(Call))
    return false;
  FunctionType *FTy = cast<FunctionType>(
      Call->getCalledValue()->getType()->getPointerElementType());
  FunctionType *NFTy = NormalizeFunctionType(FTy);
  if (NFTy == FTy)
    return false; // No change needed.

  // Convert arguments.
  SmallVector<Value *, 8> Args;
  for (unsigned I = 0; I < Call->getNumArgOperands(); ++I) {
    Value *Arg = Call->getArgOperand(I);
    if (NFTy->getParamType(I) != FTy->getParamType(I)) {
      Instruction::CastOps CastType =
          Call->getAttributes().hasAttribute(I + 1, Attribute::SExt) ?
          Instruction::SExt : Instruction::ZExt;
      Arg = CopyDebug(CastInst::Create(CastType, Arg, NFTy->getParamType(I),
                                       "arg_ext", Call), Call);
    }
    Args.push_back(Arg);
  }
  Value *CastFunc =
    CopyDebug(new BitCastInst(Call->getCalledValue(), NFTy->getPointerTo(),
                              Call->getName() + ".arg_cast", Call), Call);
  Value *Result = NULL;
  if (CallInst *OldCall = dyn_cast<CallInst>(Call)) {
    CallInst *NewCall = CopyDebug(CallInst::Create(CastFunc, Args, "", OldCall),
                                  OldCall);
    NewCall->takeName(OldCall);
    NewCall->setAttributes(OldCall->getAttributes());
    NewCall->setCallingConv(OldCall->getCallingConv());
    NewCall->setTailCall(OldCall->isTailCall());
    Result = NewCall;

    if (FTy->getReturnType() != NFTy->getReturnType()) {
      Result = CopyDebug(new TruncInst(NewCall, FTy->getReturnType(),
                                       NewCall->getName() + ".ret_trunc", Call),
                         Call);
    }
  } else if (InvokeInst *OldInvoke = dyn_cast<InvokeInst>(Call)) {
    BasicBlock *Parent = OldInvoke->getParent();
    BasicBlock *NormalDest = OldInvoke->getNormalDest();
    BasicBlock *UnwindDest = OldInvoke->getUnwindDest();

    if (FTy->getReturnType() != NFTy->getReturnType()) {
      if (BasicBlock *SplitDest = SplitCriticalEdge(Parent, NormalDest)) {
        NormalDest = SplitDest;
      }
    }

    InvokeInst *New = CopyDebug(InvokeInst::Create(CastFunc, NormalDest,
                                                   UnwindDest, Args,
                                                   "", OldInvoke),
                                OldInvoke);
    New->takeName(OldInvoke);

    if (FTy->getReturnType() != NFTy->getReturnType()) {
      Result = CopyDebug(new TruncInst(New, FTy->getReturnType(),
                                       New->getName() + ".ret_trunc",
                                       NormalDest->getTerminator()),
                         OldInvoke);
    } else {
      Result = New;
    }

    New->setAttributes(OldInvoke->getAttributes());
    New->setCallingConv(OldInvoke->getCallingConv());
  }
  Call->replaceAllUsesWith(Result);
  Call->eraseFromParent();
  return true;
}
Пример #15
0
/// HandleCallsInBlockInlinedThroughInvoke - When we inline a basic block into
/// an invoke, we have to turn all of the calls that can throw into
/// invokes.  This function analyze BB to see if there are any calls, and if so,
/// it rewrites them to be invokes that jump to InvokeDest and fills in the PHI
/// nodes in that block with the values specified in InvokeDestPHIValues.
///
/// Returns true to indicate that the next block should be skipped.
static bool HandleCallsInBlockInlinedThroughInvoke(BasicBlock *BB,
                                                   InvokeInliningInfo &Invoke) {
  for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) {
    Instruction *I = BBI++;
    
    // We only need to check for function calls: inlined invoke
    // instructions require no special handling.
    CallInst *CI = dyn_cast<CallInst>(I);
    if (CI == 0) continue;

    // LIBUNWIND: merge selector instructions.
    if (EHSelectorInst *Inner = dyn_cast<EHSelectorInst>(CI)) {
      EHSelectorInst *Outer = Invoke.getOuterSelector();
      if (!Outer) continue;

      bool innerIsOnlyCleanup = isCleanupOnlySelector(Inner);
      bool outerIsOnlyCleanup = isCleanupOnlySelector(Outer);

      // If both selectors contain only cleanups, we don't need to do
      // anything.  TODO: this is really just a very specific instance
      // of a much more general optimization.
      if (innerIsOnlyCleanup && outerIsOnlyCleanup) continue;

      // Otherwise, we just append the outer selector to the inner selector.
      SmallVector<Value*, 16> NewSelector;
      for (unsigned i = 0, e = Inner->getNumArgOperands(); i != e; ++i)
        NewSelector.push_back(Inner->getArgOperand(i));
      for (unsigned i = 2, e = Outer->getNumArgOperands(); i != e; ++i)
        NewSelector.push_back(Outer->getArgOperand(i));

      CallInst *NewInner =
        IRBuilder<>(Inner).CreateCall(Inner->getCalledValue(), NewSelector);
      // No need to copy attributes, calling convention, etc.
      NewInner->takeName(Inner);
      Inner->replaceAllUsesWith(NewInner);
      Inner->eraseFromParent();
      continue;
    }
    
    // If this call cannot unwind, don't convert it to an invoke.
    if (CI->doesNotThrow())
      continue;
    
    // Convert this function call into an invoke instruction.
    // First, split the basic block.
    BasicBlock *Split = BB->splitBasicBlock(CI, CI->getName()+".noexc");

    // Delete the unconditional branch inserted by splitBasicBlock
    BB->getInstList().pop_back();

    // LIBUNWIND: If this is a call to @llvm.eh.resume, just branch
    // directly to the new landing pad.
    if (Invoke.forwardEHResume(CI, BB)) {
      // TODO: 'Split' is now unreachable; clean it up.

      // We want to leave the original call intact so that the call
      // graph and other structures won't get misled.  We also have to
      // avoid processing the next block, or we'll iterate here forever.
      return true;
    }

    // Otherwise, create the new invoke instruction.
    ImmutableCallSite CS(CI);
    SmallVector<Value*, 8> InvokeArgs(CS.arg_begin(), CS.arg_end());
    InvokeInst *II =
      InvokeInst::Create(CI->getCalledValue(), Split,
                         Invoke.getOuterUnwindDest(),
                         InvokeArgs, CI->getName(), BB);
    II->setCallingConv(CI->getCallingConv());
    II->setAttributes(CI->getAttributes());
    
    // Make sure that anything using the call now uses the invoke!  This also
    // updates the CallGraph if present, because it uses a WeakVH.
    CI->replaceAllUsesWith(II);

    Split->getInstList().pop_front();  // Delete the original call

    // Update any PHI nodes in the exceptional block to indicate that
    // there is now a new entry in them.
    Invoke.addIncomingPHIValuesFor(BB);
    return false;
  }

  return false;
}
bool WebAssemblyLowerEmscriptenEHSjLj::runEHOnFunction(Function &F) {
  Module &M = *F.getParent();
  LLVMContext &C = F.getContext();
  IRBuilder<> IRB(C);
  bool Changed = false;
  SmallVector<Instruction *, 64> ToErase;
  SmallPtrSet<LandingPadInst *, 32> LandingPads;
  bool AllowExceptions =
      areAllExceptionsAllowed() || EHWhitelistSet.count(F.getName());

  for (BasicBlock &BB : F) {
    auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
    if (!II)
      continue;
    Changed = true;
    LandingPads.insert(II->getLandingPadInst());
    IRB.SetInsertPoint(II);

    bool NeedInvoke = AllowExceptions && canThrow(II->getCalledValue());
    if (NeedInvoke) {
      // Wrap invoke with invoke wrapper and generate preamble/postamble
      Value *Threw = wrapInvoke(II);
      ToErase.push_back(II);

      // Insert a branch based on __THREW__ variable
      Value *Cmp = IRB.CreateICmpEQ(Threw, IRB.getInt32(1), "cmp");
      IRB.CreateCondBr(Cmp, II->getUnwindDest(), II->getNormalDest());

    } else {
      // This can't throw, and we don't need this invoke, just replace it with a
      // call+branch
      SmallVector<Value *, 16> Args(II->arg_begin(), II->arg_end());
      CallInst *NewCall = IRB.CreateCall(II->getCalledValue(), Args);
      NewCall->takeName(II);
      NewCall->setCallingConv(II->getCallingConv());
      NewCall->setDebugLoc(II->getDebugLoc());
      NewCall->setAttributes(II->getAttributes());
      II->replaceAllUsesWith(NewCall);
      ToErase.push_back(II);

      IRB.CreateBr(II->getNormalDest());

      // Remove any PHI node entries from the exception destination
      II->getUnwindDest()->removePredecessor(&BB);
    }
  }

  // Process resume instructions
  for (BasicBlock &BB : F) {
    // Scan the body of the basic block for resumes
    for (Instruction &I : BB) {
      auto *RI = dyn_cast<ResumeInst>(&I);
      if (!RI)
        continue;

      // Split the input into legal values
      Value *Input = RI->getValue();
      IRB.SetInsertPoint(RI);
      Value *Low = IRB.CreateExtractValue(Input, 0, "low");
      // Create a call to __resumeException function
      IRB.CreateCall(ResumeF, {Low});
      // Add a terminator to the block
      IRB.CreateUnreachable();
      ToErase.push_back(RI);
    }
  }

  // Process llvm.eh.typeid.for intrinsics
  for (BasicBlock &BB : F) {
    for (Instruction &I : BB) {
      auto *CI = dyn_cast<CallInst>(&I);
      if (!CI)
        continue;
      const Function *Callee = CI->getCalledFunction();
      if (!Callee)
        continue;
      if (Callee->getIntrinsicID() != Intrinsic::eh_typeid_for)
        continue;

      IRB.SetInsertPoint(CI);
      CallInst *NewCI =
          IRB.CreateCall(EHTypeIDF, CI->getArgOperand(0), "typeid");
      CI->replaceAllUsesWith(NewCI);
      ToErase.push_back(CI);
    }
  }

  // Look for orphan landingpads, can occur in blocks with no predecessors
  for (BasicBlock &BB : F) {
    Instruction *I = BB.getFirstNonPHI();
    if (auto *LPI = dyn_cast<LandingPadInst>(I))
      LandingPads.insert(LPI);
  }

  // Handle all the landingpad for this function together, as multiple invokes
  // may share a single lp
  for (LandingPadInst *LPI : LandingPads) {
    IRB.SetInsertPoint(LPI);
    SmallVector<Value *, 16> FMCArgs;
    for (unsigned i = 0, e = LPI->getNumClauses(); i < e; ++i) {
      Constant *Clause = LPI->getClause(i);
      // As a temporary workaround for the lack of aggregate varargs support
      // in the interface between JS and wasm, break out filter operands into
      // their component elements.
      if (LPI->isFilter(i)) {
        auto *ATy = cast<ArrayType>(Clause->getType());
        for (unsigned j = 0, e = ATy->getNumElements(); j < e; ++j) {
          Value *EV = IRB.CreateExtractValue(Clause, makeArrayRef(j), "filter");
          FMCArgs.push_back(EV);
        }
      } else
        FMCArgs.push_back(Clause);
    }

    // Create a call to __cxa_find_matching_catch_N function
    Function *FMCF = getFindMatchingCatch(M, FMCArgs.size());
    CallInst *FMCI = IRB.CreateCall(FMCF, FMCArgs, "fmc");
    Value *Undef = UndefValue::get(LPI->getType());
    Value *Pair0 = IRB.CreateInsertValue(Undef, FMCI, 0, "pair0");
    Value *TempRet0 =
        IRB.CreateLoad(TempRet0GV, TempRet0GV->getName() + ".val");
    Value *Pair1 = IRB.CreateInsertValue(Pair0, TempRet0, 1, "pair1");

    LPI->replaceAllUsesWith(Pair1);
    ToErase.push_back(LPI);
  }

  // Erase everything we no longer need in this function
  for (Instruction *I : ToErase)
    I->eraseFromParent();

  return Changed;
}
Пример #17
0
CallGraphNode* ArgumentRecovery::recoverArguments(llvm::CallGraphNode *node)
{
	Function* fn = node->getFunction();
	if (fn == nullptr)
	{
		// "theoretical nodes", whatever that is
		return nullptr;
	}
	
	// quick exit if there isn't exactly one argument
	if (fn->arg_size() != 1)
	{
		return nullptr;
	}
	
	Argument* fnArg = fn->arg_begin();
	if (!isStructType(fnArg))
	{
		return nullptr;
	}
	
	// This is a nasty NASTY hack that relies on the AA pass being RegisterUse.
	// The data should be moved to a separate helper pass that can be queried from both the AA pass and this one.
	RegisterUse& regUse = getAnalysis<RegisterUse>();
	CallGraph& cg = getAnalysis<CallGraphWrapperPass>().getCallGraph();
	
	const auto* modRefInfo = regUse.getModRefInfo(fn);
	assert(modRefInfo != nullptr);
	
	// At this point we pretty much know that we're going to modify the function, so start doing that.
	// Get register offsets from the old function before we start mutilating it.
	auto& registerMap = exposeAllRegisters(fn);
	
	// Create a new function prototype, asking RegisterUse for which registers should be passed in, and how.
	
	LLVMContext& ctx = fn->getContext();
	SmallVector<pair<const char*, Type*>, 16> parameters;
	Type* int64 = Type::getInt64Ty(ctx);
	Type* int64ptr = Type::getInt64PtrTy(ctx);
	for (const auto& pair : *modRefInfo)
	{
		if (pair.second != RegisterUse::NoModRef)
		{
			Type* paramType = (pair.second & RegisterUse::Mod) == RegisterUse::Mod ? int64ptr : int64;
			parameters.push_back({pair.first, paramType});
		}
	}
	
	// Order parameters.
	// FIXME: This could use an ABI-specific sort routine. For now, use a lexicographical sort.
	sort(parameters.begin(), parameters.end(), [](const pair<const char*, Type*>& a, const pair<const char*, Type*>& b) {
		return strcmp(a.first, b.first) < 0;
	});
	
	// Extract parameter types.
	SmallVector<Type*, 16> parameterTypes;
	for (const auto& pair : parameters)
	{
		parameterTypes.push_back(pair.second);
	}
	
	// Ideally, we would also do caller analysis here to figure out which output registers are never read, such that
	// we can either eliminate them from the parameter list or pass them by value instead of by address.
	// We would also pick a return value.
	FunctionType* newFunctionType = FunctionType::get(Type::getVoidTy(ctx), parameterTypes, false);

	Function* newFunc = Function::Create(newFunctionType, fn->getLinkage());
	newFunc->copyAttributesFrom(fn);
	fn->getParent()->getFunctionList().insert(fn, newFunc);
	newFunc->takeName(fn);
	fn->setName("__hollow_husk__" + newFunc->getName());
	
	// Set argument names
	size_t i = 0;
	
	for (Argument& arg : newFunc->args())
	{
		arg.setName(parameters[i].first);
		i++;
	}
	
	// update call graph
	CallGraphNode* newFuncNode = cg.getOrInsertFunction(newFunc);
	CallGraphNode* oldFuncNode = cg[fn];
	
	// loop over callers and transform call sites.
	while (!fn->use_empty())
	{
		CallSite cs(fn->user_back());
		Instruction* call = cast<CallInst>(cs.getInstruction());
		Function* caller = call->getParent()->getParent();
		
		auto& registerPositions = exposeAllRegisters(caller);
		SmallVector<Value*, 16> callParameters;
		for (const auto& pair : parameters)
		{
			// HACKHACK: find a pointer to a 64-bit int in the set.
			Value* registerPointer = nullptr;
			auto range = registerPositions.equal_range(pair.first);
			for (auto iter = range.first; iter != range.second; iter++)
			{
				if (auto gep = dyn_cast<GetElementPtrInst>(iter->second))
				if (gep->getResultElementType() == int64)
				{
					registerPointer = gep;
					break;
				}
			}
			
			assert(registerPointer != nullptr);
			
			if (isa<PointerType>(pair.second))
			{
				callParameters.push_back(registerPointer);
			}
			else
			{
				// Create a load instruction. GVN will get rid of it if it's unnecessary.
				LoadInst* load = new LoadInst(registerPointer, pair.first, call);
				callParameters.push_back(load);
			}
		}
		
		CallInst* newCall = CallInst::Create(newFunc, callParameters, "", call);
		
		// Update AA
		regUse.replaceWithNewValue(call, newCall);
		
		// Update call graph
		CallGraphNode* calleeNode = cg[caller];
		calleeNode->replaceCallEdge(cs, CallSite(newCall), newFuncNode);
		
		// Finish replacing
		if (!call->use_empty())
		{
			call->replaceAllUsesWith(newCall);
			newCall->takeName(call);
		}
		
		call->eraseFromParent();
	}
	
	// Do not fix functions without a body.
	if (!fn->isDeclaration())
	{
		// Fix up function code. Start by moving everything into the new function.
		newFunc->getBasicBlockList().splice(newFunc->begin(), fn->getBasicBlockList());
		newFuncNode->stealCalledFunctionsFrom(oldFuncNode);
		
		// Change register uses
		size_t argIndex = 0;
		auto& argList = newFunc->getArgumentList();
		
		// Create a temporary insertion point. We don't want an existing instruction since chances are that we'll remove it.
		Instruction* insertionPoint = BinaryOperator::CreateAdd(ConstantInt::get(int64, 0), ConstantInt::get(int64, 0), "noop", newFunc->begin()->begin());
		for (auto iter = argList.begin(); iter != argList.end(); iter++, argIndex++)
		{
			Value* replaceWith = iter;
			const auto& paramTuple = parameters[argIndex];
			if (!isa<PointerType>(paramTuple.second))
			{
				// Create an alloca, copy value from parameter, replace GEP with alloca.
				// This is ugly code gen, but it will optimize easily, and still work if
				// we need a pointer reference to the register.
				auto alloca = new AllocaInst(paramTuple.second, paramTuple.first, insertionPoint);
				new StoreInst(iter, alloca, insertionPoint);
				replaceWith = alloca;
			}
			
			// Replace all uses with new instance.
			auto iterPair = registerMap.equal_range(paramTuple.first);
			for (auto registerMapIter = iterPair.first; registerMapIter != iterPair.second; registerMapIter++)
			{
				auto& registerValue = registerMapIter->second;
				registerValue->replaceAllUsesWith(replaceWith);
				cast<Instruction>(registerValue)->eraseFromParent();
				registerValue = replaceWith;
			}
		}
		
		// At this point, the uses of the argument struct left should be:
		// * preserved registers
		// * indirect jumps
		const auto& target = getAnalysis<TargetInfo>();
		while (!fnArg->use_empty())
		{
			auto lastUser = fnArg->user_back();
			if (auto user = dyn_cast<GetElementPtrInst>(lastUser))
			{
				// Promote register to alloca.
				const char* maybeName = target.registerName(*user);
				const char* regName = target.largestOverlappingRegister(maybeName);
				assert(regName != nullptr);
				
				auto alloca = new AllocaInst(user->getResultElementType(), regName, insertionPoint);
				user->replaceAllUsesWith(alloca);
				user->eraseFromParent();
			}
			else
			{
				auto call = cast<CallInst>(lastUser);
				
				Function* intrin = nullptr;
				StringRef intrinName = call->getCalledFunction()->getName();
				if (intrinName == "x86_jump_intrin")
				{
					intrin = indirectJump;
				}
				else if (intrinName == "x86_call_intrin")
				{
					intrin = indirectCall;
				}
				else
				{
					assert(false);
					// Can't decompile this function. Delete its body.
					newFunc->deleteBody();
					insertionPoint = nullptr;
					break;
				}
				
				// Replace intrinsic with another intrinsic.
				Value* jumpTarget = call->getOperand(2);
				SmallVector<Value*, 16> callArgs;
				callArgs.push_back(jumpTarget);
				for (Argument& arg : argList)
				{
					callArgs.push_back(&arg);
				}
				
				CallInst* varargCall = CallInst::Create(intrin, callArgs, "", call);
				newFuncNode->replaceCallEdge(CallSite(call), CallSite(varargCall), cg[intrin]);
				regUse.replaceWithNewValue(call, varargCall);
				
				varargCall->takeName(call);
				call->eraseFromParent();
			}
		}
		if (insertionPoint != nullptr)
		{
			// no longer needed
			insertionPoint->eraseFromParent();
		}
	}
	
	// At this point nothing should be using the old register argument anymore. (Pray!)
	// Leave the hollow husk of the old function in place to be erased by global DCE.
	registerAddresses[newFunc] = move(registerMap);
	registerAddresses.erase(fn);
	
	// Should be all.
	return newFuncNode;
}