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; }
// 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; }
/// 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(); }
/// 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(); }
/// 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(); }
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; }
/// 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; }
/// 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; }
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; }