diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp | 50 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Utils/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Utils/GuardUtils.cpp | 64 | 
3 files changed, 67 insertions, 48 deletions
diff --git a/llvm/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp b/llvm/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp index 070114a84cc..fac57014740 100644 --- a/llvm/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp +++ b/llvm/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp @@ -17,23 +17,16 @@  #include "llvm/ADT/SmallVector.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 +39,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. @@ -108,7 +62,7 @@ static bool lowerGuardIntrinsic(Function &F) {    DeoptIntrinsic->setCallingConv(GuardDecl->getCallingConv());    for (auto *CI : ToLower) { -    MakeGuardControlFlowExplicit(DeoptIntrinsic, CI); +    makeGuardControlFlowExplicit(DeoptIntrinsic, CI);      CI->eraseFromParent();    } diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt b/llvm/lib/Transforms/Utils/CMakeLists.txt index f45bc22f55e..3dd5fe81166 100644 --- a/llvm/lib/Transforms/Utils/CMakeLists.txt +++ b/llvm/lib/Transforms/Utils/CMakeLists.txt @@ -18,6 +18,7 @@ add_llvm_library(LLVMTransformUtils    FunctionComparator.cpp    FunctionImportUtils.cpp    GlobalStatus.cpp +  GuardUtils.cpp    InlineFunction.cpp    ImportedFunctionsInliningStatistics.cpp    InstructionNamer.cpp diff --git a/llvm/lib/Transforms/Utils/GuardUtils.cpp b/llvm/lib/Transforms/Utils/GuardUtils.cpp new file mode 100644 index 00000000000..08de0a4c53e --- /dev/null +++ b/llvm/lib/Transforms/Utils/GuardUtils.cpp @@ -0,0 +1,64 @@ +//===-- GuardUtils.cpp - Utils for work with guards -------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Utils that are used to perform transformations related to guards and their +// conditions. +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Utils/GuardUtils.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/MDBuilder.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.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)")); + +void llvm::makeGuardControlFlowExplicit(Function *DeoptIntrinsic, +                                        CallInst *Guard) { +  OperandBundleDef DeoptOB(*Guard->getOperandBundle(LLVMContext::OB_deopt)); +  SmallVector<Value *, 4> Args(std::next(Guard->arg_begin()), Guard->arg_end()); + +  auto *CheckBB = Guard->getParent(); +  auto *DeoptBlockTerm = +      SplitBlockAndInsertIfThen(Guard->getArgOperand(0), Guard, 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 = Guard->getMetadata(LLVMContext::MD_make_implicit)) +    CheckBI->setMetadata(LLVMContext::MD_make_implicit, MD); + +  MDBuilder MDB(Guard->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(Guard->getCallingConv()); +  DeoptBlockTerm->eraseFromParent(); +}  | 

