diff options
Diffstat (limited to 'lib/Transforms/Scalar/LowerGuardIntrinsic.cpp')
-rw-r--r-- | lib/Transforms/Scalar/LowerGuardIntrinsic.cpp | 57 |
1 files changed, 5 insertions, 52 deletions
diff --git a/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp b/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp index 070114a84cc5..4867b33d671f 100644 --- a/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp +++ b/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp @@ -15,25 +15,19 @@ #include "llvm/Transforms/Scalar/LowerGuardIntrinsic.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/GuardUtils.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Function.h" -#include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" -#include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" #include "llvm/Pass.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/GuardUtils.h" using namespace llvm; -static cl::opt<uint32_t> PredicatePassBranchWeight( - "guards-predicate-pass-branch-weight", cl::Hidden, cl::init(1 << 20), - cl::desc("The probability of a guard failing is assumed to be the " - "reciprocal of this value (default = 1 << 20)")); - namespace { struct LowerGuardIntrinsicLegacyPass : public FunctionPass { static char ID; @@ -46,45 +40,6 @@ struct LowerGuardIntrinsicLegacyPass : public FunctionPass { }; } -static void MakeGuardControlFlowExplicit(Function *DeoptIntrinsic, - CallInst *CI) { - OperandBundleDef DeoptOB(*CI->getOperandBundle(LLVMContext::OB_deopt)); - SmallVector<Value *, 4> Args(std::next(CI->arg_begin()), CI->arg_end()); - - auto *CheckBB = CI->getParent(); - auto *DeoptBlockTerm = - SplitBlockAndInsertIfThen(CI->getArgOperand(0), CI, true); - - auto *CheckBI = cast<BranchInst>(CheckBB->getTerminator()); - - // SplitBlockAndInsertIfThen inserts control flow that branches to - // DeoptBlockTerm if the condition is true. We want the opposite. - CheckBI->swapSuccessors(); - - CheckBI->getSuccessor(0)->setName("guarded"); - CheckBI->getSuccessor(1)->setName("deopt"); - - if (auto *MD = CI->getMetadata(LLVMContext::MD_make_implicit)) - CheckBI->setMetadata(LLVMContext::MD_make_implicit, MD); - - MDBuilder MDB(CI->getContext()); - CheckBI->setMetadata(LLVMContext::MD_prof, - MDB.createBranchWeights(PredicatePassBranchWeight, 1)); - - IRBuilder<> B(DeoptBlockTerm); - auto *DeoptCall = B.CreateCall(DeoptIntrinsic, Args, {DeoptOB}, ""); - - if (DeoptIntrinsic->getReturnType()->isVoidTy()) { - B.CreateRetVoid(); - } else { - DeoptCall->setName("deoptcall"); - B.CreateRet(DeoptCall); - } - - DeoptCall->setCallingConv(CI->getCallingConv()); - DeoptBlockTerm->eraseFromParent(); -} - static bool lowerGuardIntrinsic(Function &F) { // Check if we can cheaply rule out the possibility of not having any work to // do. @@ -95,10 +50,8 @@ static bool lowerGuardIntrinsic(Function &F) { SmallVector<CallInst *, 8> ToLower; for (auto &I : instructions(F)) - if (auto *CI = dyn_cast<CallInst>(&I)) - if (auto *F = CI->getCalledFunction()) - if (F->getIntrinsicID() == Intrinsic::experimental_guard) - ToLower.push_back(CI); + if (isGuard(&I)) + ToLower.push_back(cast<CallInst>(&I)); if (ToLower.empty()) return false; @@ -108,7 +61,7 @@ static bool lowerGuardIntrinsic(Function &F) { DeoptIntrinsic->setCallingConv(GuardDecl->getCallingConv()); for (auto *CI : ToLower) { - MakeGuardControlFlowExplicit(DeoptIntrinsic, CI); + makeGuardControlFlowExplicit(DeoptIntrinsic, CI); CI->eraseFromParent(); } |