#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm-c/Transforms/PassManagerBuilder.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/CFLAndersAliasAnalysis.h"
#include "llvm/Analysis/CFLSteensAliasAnalysis.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/ScopedNoAliasAA.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Target/CGPassBuilderOption.h"
#include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/Attributor.h"
#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
#include "llvm/Transforms/IPO/FunctionAttrs.h"
#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
#include "llvm/Transforms/InstCombine/InstCombine.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/GVN.h"
#include "llvm/Transforms/Scalar/LICM.h"
#include "llvm/Transforms/Scalar/LoopUnrollPass.h"
#include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
#include "llvm/Transforms/Utils.h"
#include "llvm/Transforms/Vectorize.h"
using namespace llvm;
namespace llvm {
cl::opt<bool> RunPartialInlining("enable-partial-inlining", cl::Hidden,
                                 cl::desc("Run Partial inlinining pass"));
static cl::opt<bool>
UseGVNAfterVectorization("use-gvn-after-vectorization",
  cl::init(false), cl::Hidden,
  cl::desc("Run GVN instead of Early CSE after vectorization passes"));
cl::opt<bool> ExtraVectorizerPasses(
    "extra-vectorizer-passes", cl::init(false), cl::Hidden,
    cl::desc("Run cleanup optimization passes after vectorization."));
static cl::opt<bool>
RunLoopRerolling("reroll-loops", cl::Hidden,
                 cl::desc("Run the loop rerolling pass"));
cl::opt<bool> RunNewGVN("enable-newgvn", cl::init(false), cl::Hidden,
                        cl::desc("Run the NewGVN pass"));
static cl::opt<::CFLAAType>
    UseCFLAA("use-cfl-aa", cl::init(::CFLAAType::None), cl::Hidden,
             cl::desc("Enable the new, experimental CFL alias analysis"),
             cl::values(clEnumValN(::CFLAAType::None, "none", "Disable CFL-AA"),
                        clEnumValN(::CFLAAType::Steensgaard, "steens",
                                   "Enable unification-based CFL-AA"),
                        clEnumValN(::CFLAAType::Andersen, "anders",
                                   "Enable inclusion-based CFL-AA"),
                        clEnumValN(::CFLAAType::Both, "both",
                                   "Enable both variants of CFL-AA")));
cl::opt<bool> EnableLoopInterchange(
    "enable-loopinterchange", cl::init(false), cl::Hidden,
    cl::desc("Enable the experimental LoopInterchange Pass"));
cl::opt<bool> EnableUnrollAndJam("enable-unroll-and-jam", cl::init(false),
                                 cl::Hidden,
                                 cl::desc("Enable Unroll And Jam Pass"));
cl::opt<bool> EnableLoopFlatten("enable-loop-flatten", cl::init(false),
                                cl::Hidden,
                                cl::desc("Enable the LoopFlatten Pass"));
cl::opt<bool> EnableDFAJumpThreading("enable-dfa-jump-thread",
                                     cl::desc("Enable DFA jump threading."),
                                     cl::init(false), cl::Hidden);
cl::opt<bool> EnableHotColdSplit("hot-cold-split",
                                 cl::desc("Enable hot-cold splitting pass"));
cl::opt<bool> EnableIROutliner("ir-outliner", cl::init(false), cl::Hidden,
    cl::desc("Enable ir outliner pass"));
static cl::opt<bool> UseLoopVersioningLICM(
    "enable-loop-versioning-licm", cl::init(false), cl::Hidden,
    cl::desc("Enable the experimental Loop Versioning LICM pass"));
cl::opt<bool>
    DisablePreInliner("disable-preinline", cl::init(false), cl::Hidden,
                      cl::desc("Disable pre-instrumentation inliner"));
cl::opt<int> PreInlineThreshold(
    "preinline-threshold", cl::Hidden, cl::init(75),
    cl::desc("Control the amount of inlining in pre-instrumentation inliner "
             "(default = 75)"));
cl::opt<bool>
    EnableGVNHoist("enable-gvn-hoist",
                   cl::desc("Enable the GVN hoisting pass (default = off)"));
static cl::opt<bool>
    DisableLibCallsShrinkWrap("disable-libcalls-shrinkwrap", cl::init(false),
                              cl::Hidden,
                              cl::desc("Disable shrink-wrap library calls"));
cl::opt<bool>
    EnableGVNSink("enable-gvn-sink",
                  cl::desc("Enable the GVN sinking pass (default = off)"));
cl::opt<bool>
    EnableCHR("enable-chr", cl::init(true), cl::Hidden,
              cl::desc("Enable control height reduction optimization (CHR)"));
cl::opt<bool> FlattenedProfileUsed(
    "flattened-profile-used", cl::init(false), cl::Hidden,
    cl::desc("Indicate the sample profile being used is flattened, i.e., "
             "no inline hierachy exists in the profile. "));
cl::opt<bool> EnableOrderFileInstrumentation(
    "enable-order-file-instrumentation", cl::init(false), cl::Hidden,
    cl::desc("Enable order file instrumentation (default = off)"));
cl::opt<bool> EnableMatrix(
    "enable-matrix", cl::init(false), cl::Hidden,
    cl::desc("Enable lowering of the matrix intrinsics"));
cl::opt<bool> EnableConstraintElimination(
    "enable-constraint-elimination", cl::init(false), cl::Hidden,
    cl::desc(
        "Enable pass to eliminate conditions based on linear constraints."));
cl::opt<bool> EnableFunctionSpecialization(
    "enable-function-specialization", cl::init(false), cl::Hidden,
    cl::desc("Enable Function Specialization pass"));
cl::opt<AttributorRunOption> AttributorRun(
    "attributor-enable", cl::Hidden, cl::init(AttributorRunOption::NONE),
    cl::desc("Enable the attributor inter-procedural deduction pass."),
    cl::values(clEnumValN(AttributorRunOption::ALL, "all",
                          "enable all attributor runs"),
               clEnumValN(AttributorRunOption::MODULE, "module",
                          "enable module-wide attributor runs"),
               clEnumValN(AttributorRunOption::CGSCC, "cgscc",
                          "enable call graph SCC attributor runs"),
               clEnumValN(AttributorRunOption::NONE, "none",
                          "disable attributor runs")));
extern cl::opt<bool> EnableKnowledgeRetention;
} 
PassManagerBuilder::PassManagerBuilder() {
    OptLevel = 2;
    SizeLevel = 0;
    LibraryInfo = nullptr;
    Inliner = nullptr;
    DisableUnrollLoops = false;
    SLPVectorize = false;
    LoopVectorize = true;
    LoopsInterleaved = true;
    RerollLoops = RunLoopRerolling;
    NewGVN = RunNewGVN;
    LicmMssaOptCap = SetLicmMssaOptCap;
    LicmMssaNoAccForPromotionCap = SetLicmMssaNoAccForPromotionCap;
    DisableGVNLoadPRE = false;
    ForgetAllSCEVInLoopUnroll = ForgetSCEVInLoopUnroll;
    VerifyInput = false;
    VerifyOutput = false;
    MergeFunctions = false;
    DivergentTarget = false;
    CallGraphProfile = true;
}
PassManagerBuilder::~PassManagerBuilder() {
  delete LibraryInfo;
  delete Inliner;
}
static ManagedStatic<
    SmallVector<std::tuple<PassManagerBuilder::ExtensionPointTy,
                           PassManagerBuilder::ExtensionFn,
                           PassManagerBuilder::GlobalExtensionID>,
                8>>
    GlobalExtensions;
static PassManagerBuilder::GlobalExtensionID GlobalExtensionsCounter;
static bool GlobalExtensionsNotEmpty() {
  return GlobalExtensions.isConstructed() && !GlobalExtensions->empty();
}
PassManagerBuilder::GlobalExtensionID
PassManagerBuilder::addGlobalExtension(PassManagerBuilder::ExtensionPointTy Ty,
                                       PassManagerBuilder::ExtensionFn Fn) {
  auto ExtensionID = GlobalExtensionsCounter++;
  GlobalExtensions->push_back(std::make_tuple(Ty, std::move(Fn), ExtensionID));
  return ExtensionID;
}
void PassManagerBuilder::removeGlobalExtension(
    PassManagerBuilder::GlobalExtensionID ExtensionID) {
      if (!GlobalExtensions.isConstructed())
    return;
  auto GlobalExtension =
      llvm::find_if(*GlobalExtensions, [ExtensionID](const auto &elem) {
        return std::get<2>(elem) == ExtensionID;
      });
  assert(GlobalExtension != GlobalExtensions->end() &&
         "The extension ID to be removed should always be valid.");
  GlobalExtensions->erase(GlobalExtension);
}
void PassManagerBuilder::addExtension(ExtensionPointTy Ty, ExtensionFn Fn) {
  Extensions.push_back(std::make_pair(Ty, std::move(Fn)));
}
void PassManagerBuilder::addExtensionsToPM(ExtensionPointTy ETy,
                                           legacy::PassManagerBase &PM) const {
  if (GlobalExtensionsNotEmpty()) {
    for (auto &Ext : *GlobalExtensions) {
      if (std::get<0>(Ext) == ETy)
        std::get<1>(Ext)(*this, PM);
    }
  }
  for (unsigned i = 0, e = Extensions.size(); i != e; ++i)
    if (Extensions[i].first == ETy)
      Extensions[i].second(*this, PM);
}
void PassManagerBuilder::addInitialAliasAnalysisPasses(
    legacy::PassManagerBase &PM) const {
  switch (UseCFLAA) {
  case ::CFLAAType::Steensgaard:
    PM.add(createCFLSteensAAWrapperPass());
    break;
  case ::CFLAAType::Andersen:
    PM.add(createCFLAndersAAWrapperPass());
    break;
  case ::CFLAAType::Both:
    PM.add(createCFLSteensAAWrapperPass());
    PM.add(createCFLAndersAAWrapperPass());
    break;
  default:
    break;
  }
        PM.add(createTypeBasedAAWrapperPass());
  PM.add(createScopedNoAliasAAWrapperPass());
}
void PassManagerBuilder::populateFunctionPassManager(
    legacy::FunctionPassManager &FPM) {
  addExtensionsToPM(EP_EarlyAsPossible, FPM);
    if (LibraryInfo)
    FPM.add(new TargetLibraryInfoWrapperPass(*LibraryInfo));
          if (EnableMatrix && OptLevel == 0)
    FPM.add(createLowerMatrixIntrinsicsMinimalPass());
  if (OptLevel == 0) return;
  addInitialAliasAnalysisPasses(FPM);
      FPM.add(createLowerExpectIntrinsicPass());
  FPM.add(createCFGSimplificationPass());
  FPM.add(createSROAPass());
  FPM.add(createEarlyCSEPass());
}
void PassManagerBuilder::addFunctionSimplificationPasses(
    legacy::PassManagerBase &MPM) {
      assert(OptLevel >= 1 && "Calling function optimizer with no optimization level!");
  MPM.add(createSROAPass());
  MPM.add(createEarlyCSEPass(true ));   if (EnableKnowledgeRetention)
    MPM.add(createAssumeSimplifyPass());
  if (OptLevel > 1) {
    if (EnableGVNHoist)
      MPM.add(createGVNHoistPass());
    if (EnableGVNSink) {
      MPM.add(createGVNSinkPass());
      MPM.add(createCFGSimplificationPass(
          SimplifyCFGOptions().convertSwitchRangeToICmp(true)));
    }
  }
  if (EnableConstraintElimination)
    MPM.add(createConstraintEliminationPass());
  if (OptLevel > 1) {
        MPM.add(createSpeculativeExecutionIfHasBranchDivergencePass());
    MPM.add(createJumpThreadingPass());             MPM.add(createCorrelatedValuePropagationPass());   }
  MPM.add(
      createCFGSimplificationPass(SimplifyCFGOptions().convertSwitchRangeToICmp(
          true)));     if (OptLevel > 2)
    MPM.add(createAggressiveInstCombinerPass());
  MPM.add(createInstructionCombiningPass());
  if (SizeLevel == 0 && !DisableLibCallsShrinkWrap)
    MPM.add(createLibCallsShrinkWrapPass());
  addExtensionsToPM(EP_Peephole, MPM);
    if (OptLevel > 1)
    MPM.add(createTailCallEliminationPass());   MPM.add(
      createCFGSimplificationPass(SimplifyCFGOptions().convertSwitchRangeToICmp(
          true)));                              MPM.add(createReassociatePass());           
      if (EnableMatrix)
    MPM.add(createVectorCombinePass());
  
        MPM.add(createLoopInstSimplifyPass());
  MPM.add(createLoopSimplifyCFGPass());
              MPM.add(createLICMPass(LicmMssaOptCap, LicmMssaNoAccForPromotionCap,
                         false));
    MPM.add(createLoopRotatePass(SizeLevel == 2 ? 0 : -1, false));
    MPM.add(createLICMPass(LicmMssaOptCap, LicmMssaNoAccForPromotionCap,
                         true));
  MPM.add(createSimpleLoopUnswitchLegacyPass(OptLevel == 3));
        MPM.add(createCFGSimplificationPass(
      SimplifyCFGOptions().convertSwitchRangeToICmp(true)));
  MPM.add(createInstructionCombiningPass());
    if (EnableLoopFlatten) {
    MPM.add(createLoopFlattenPass());     MPM.add(createLoopSimplifyCFGPass());
  }
  MPM.add(createLoopIdiomPass());               MPM.add(createIndVarSimplifyPass());          addExtensionsToPM(EP_LateLoopOptimizations, MPM);
  MPM.add(createLoopDeletionPass());          
  if (EnableLoopInterchange)
    MPM.add(createLoopInterchangePass()); 
    MPM.add(createSimpleLoopUnrollPass(OptLevel, DisableUnrollLoops,
                                     ForgetAllSCEVInLoopUnroll));
  addExtensionsToPM(EP_LoopOptimizerEnd, MPM);
  
    MPM.add(createSROAPass());
  if (OptLevel > 1) {
    MPM.add(createMergedLoadStoreMotionPass());     MPM.add(NewGVN ? createNewGVNPass()
                   : createGVNPass(DisableGVNLoadPRE));   }
  MPM.add(createSCCPPass());                  
  if (EnableConstraintElimination)
    MPM.add(createConstraintEliminationPass());
        MPM.add(createBitTrackingDCEPass());        
      MPM.add(createInstructionCombiningPass());
  addExtensionsToPM(EP_Peephole, MPM);
  if (OptLevel > 1) {
    if (EnableDFAJumpThreading && SizeLevel == 0)
      MPM.add(createDFAJumpThreadingPass());
    MPM.add(createJumpThreadingPass());             MPM.add(createCorrelatedValuePropagationPass());
  }
  MPM.add(createAggressiveDCEPass()); 
  MPM.add(createMemCpyOptPass());                   if (OptLevel > 1) {
    MPM.add(createDeadStoreEliminationPass());      MPM.add(createLICMPass(LicmMssaOptCap, LicmMssaNoAccForPromotionCap,
                           true));
  }
  addExtensionsToPM(EP_ScalarOptimizerLate, MPM);
  if (RerollLoops)
    MPM.add(createLoopRerollPass());
    MPM.add(createCFGSimplificationPass(
      SimplifyCFGOptions().hoistCommonInsts(true).sinkCommonInsts(true)));
    MPM.add(createInstructionCombiningPass());
  addExtensionsToPM(EP_Peephole, MPM);
}
void PassManagerBuilder::addVectorPasses(legacy::PassManagerBase &PM,
                                         bool IsFullLTO) {
  PM.add(createLoopVectorizePass(!LoopsInterleaved, !LoopVectorize));
  if (IsFullLTO) {
                                    if (EnableUnrollAndJam && !DisableUnrollLoops)
      PM.add(createLoopUnrollAndJamPass(OptLevel));
    PM.add(createLoopUnrollPass(OptLevel, DisableUnrollLoops,
                                ForgetAllSCEVInLoopUnroll));
    PM.add(createWarnMissedTransformationsPass());
  }
  if (!IsFullLTO) {
            PM.add(createLoopLoadEliminationPass());
  }
    PM.add(createInstructionCombiningPass());
  if (OptLevel > 1 && ExtraVectorizerPasses) {
                            PM.add(createEarlyCSEPass());
    PM.add(createCorrelatedValuePropagationPass());
    PM.add(createInstructionCombiningPass());
    PM.add(createLICMPass(LicmMssaOptCap, LicmMssaNoAccForPromotionCap,
                          true));
    PM.add(createSimpleLoopUnswitchLegacyPass());
    PM.add(createCFGSimplificationPass(
        SimplifyCFGOptions().convertSwitchRangeToICmp(true)));
    PM.add(createInstructionCombiningPass());
  }
      
            PM.add(createCFGSimplificationPass(SimplifyCFGOptions()
                                         .forwardSwitchCondToPhi(true)
                                         .convertSwitchRangeToICmp(true)
                                         .convertSwitchToLookupTable(true)
                                         .needCanonicalLoops(false)
                                         .hoistCommonInsts(true)
                                         .sinkCommonInsts(true)));
  if (IsFullLTO) {
    PM.add(createSCCPPass());                     PM.add(createInstructionCombiningPass());     PM.add(createBitTrackingDCEPass());
  }
    if (SLPVectorize) {
    PM.add(createSLPVectorizerPass());
    if (OptLevel > 1 && ExtraVectorizerPasses)
      PM.add(createEarlyCSEPass());
  }
    PM.add(createVectorCombinePass());
  if (!IsFullLTO) {
    addExtensionsToPM(EP_Peephole, PM);
    PM.add(createInstructionCombiningPass());
    if (EnableUnrollAndJam && !DisableUnrollLoops) {
                        PM.add(createLoopUnrollAndJamPass(OptLevel));
    }
        PM.add(createLoopUnrollPass(OptLevel, DisableUnrollLoops,
                                ForgetAllSCEVInLoopUnroll));
    if (!DisableUnrollLoops) {
            PM.add(createInstructionCombiningPass());
                              PM.add(createLICMPass(LicmMssaOptCap, LicmMssaNoAccForPromotionCap,
                            true));
    }
    PM.add(createWarnMissedTransformationsPass());
  }
      PM.add(createAlignmentFromAssumptionsPass());
  if (IsFullLTO)
    PM.add(createInstructionCombiningPass());
}
void PassManagerBuilder::populateModulePassManager(
    legacy::PassManagerBase &MPM) {
  MPM.add(createAnnotation2MetadataLegacyPass());
    MPM.add(createForceFunctionAttrsLegacyPass());
      if (OptLevel == 0) {
    if (Inliner) {
      MPM.add(Inliner);
      Inliner = nullptr;
    }
                        if (MergeFunctions)
      MPM.add(createMergeFunctionsPass());
    else if (GlobalExtensionsNotEmpty() || !Extensions.empty())
      MPM.add(createBarrierNoopPass());
    addExtensionsToPM(EP_EnabledOnOptLevel0, MPM);
    MPM.add(createAnnotationRemarksLegacyPass());
    return;
  }
    if (LibraryInfo)
    MPM.add(new TargetLibraryInfoWrapperPass(*LibraryInfo));
  addInitialAliasAnalysisPasses(MPM);
    MPM.add(createInferFunctionAttrsLegacyPass());
    if (AttributorRun & AttributorRunOption::MODULE)
    MPM.add(createAttributorLegacyPass());
  addExtensionsToPM(EP_ModuleOptimizerEarly, MPM);
  if (OptLevel > 2)
    MPM.add(createCallSiteSplittingPass());
    if (OptLevel > 2 && EnableFunctionSpecialization)
    MPM.add(createFunctionSpecializationPass());
  MPM.add(createIPSCCPPass());            MPM.add(createCalledValuePropagationPass());
  MPM.add(createGlobalOptimizerPass());     MPM.add(createPromoteMemoryToRegisterPass());
  MPM.add(createDeadArgEliminationPass()); 
  MPM.add(createInstructionCombiningPass());   addExtensionsToPM(EP_Peephole, MPM);
  MPM.add(
      createCFGSimplificationPass(SimplifyCFGOptions().convertSwitchRangeToICmp(
          true))); 
        MPM.add(createGlobalsAAWrapperPass());
    MPM.add(createPruneEHPass());   bool RunInliner = false;
  if (Inliner) {
    MPM.add(Inliner);
    Inliner = nullptr;
    RunInliner = true;
  }
    if (AttributorRun & AttributorRunOption::CGSCC)
    MPM.add(createAttributorCGSCCLegacyPass());
      if (OptLevel > 1)
    MPM.add(createOpenMPOptCGSCCLegacyPass());
  MPM.add(createPostOrderFunctionAttrsLegacyPass());
  addExtensionsToPM(EP_CGSCCOptimizerLate, MPM);
  addFunctionSimplificationPasses(MPM);
        MPM.add(createBarrierNoopPass());
  if (RunPartialInlining)
    MPM.add(createPartialInliningPass());
  if (OptLevel > 1)
                                        MPM.add(createEliminateAvailableExternallyPass());
  MPM.add(createReversePostOrderFunctionAttrsPass());
              if (RunInliner) {
    MPM.add(createGlobalOptimizerPass());
    MPM.add(createGlobalDCEPass());
  }
            if (UseLoopVersioningLICM) {
    MPM.add(createLoopVersioningLICMPass());        MPM.add(createLICMPass(LicmMssaOptCap, LicmMssaNoAccForPromotionCap,
                           true));
  }
                                MPM.add(createGlobalsAAWrapperPass());
  MPM.add(createFloat2IntPass());
  MPM.add(createLowerConstantIntrinsicsPass());
  if (EnableMatrix) {
    MPM.add(createLowerMatrixIntrinsicsPass());
                MPM.add(createEarlyCSEPass(false));
  }
  addExtensionsToPM(EP_VectorizerStart, MPM);
        MPM.add(createLoopRotatePass(SizeLevel == 2 ? 0 : -1, false));
          MPM.add(createLoopDistributePass());
  addVectorPasses(MPM,  false);
    MPM.add(createStripDeadPrototypesPass()); 
      if (OptLevel > 1) {
    MPM.add(createGlobalDCEPass());             MPM.add(createConstantMergePass());       }
      if (EnableHotColdSplit)
    MPM.add(createHotColdSplittingPass());
  if (EnableIROutliner)
    MPM.add(createIROutlinerPass());
  if (MergeFunctions)
    MPM.add(createMergeFunctionsPass());
          MPM.add(createLoopSinkPass());
    MPM.add(createInstSimplifyLegacyPass());
        MPM.add(createDivRemPairsPass());
      MPM.add(createCFGSimplificationPass(
      SimplifyCFGOptions().convertSwitchRangeToICmp(true)));
  addExtensionsToPM(EP_OptimizerLast, MPM);
  MPM.add(createAnnotationRemarksLegacyPass());
}
LLVMPassManagerBuilderRef LLVMPassManagerBuilderCreate() {
  PassManagerBuilder *PMB = new PassManagerBuilder();
  return wrap(PMB);
}
void LLVMPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB) {
  PassManagerBuilder *Builder = unwrap(PMB);
  delete Builder;
}
void
LLVMPassManagerBuilderSetOptLevel(LLVMPassManagerBuilderRef PMB,
                                  unsigned OptLevel) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->OptLevel = OptLevel;
}
void
LLVMPassManagerBuilderSetSizeLevel(LLVMPassManagerBuilderRef PMB,
                                   unsigned SizeLevel) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->SizeLevel = SizeLevel;
}
void
LLVMPassManagerBuilderSetDisableUnitAtATime(LLVMPassManagerBuilderRef PMB,
                                            LLVMBool Value) {
  }
void
LLVMPassManagerBuilderSetDisableUnrollLoops(LLVMPassManagerBuilderRef PMB,
                                            LLVMBool Value) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->DisableUnrollLoops = Value;
}
void
LLVMPassManagerBuilderSetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef PMB,
                                                 LLVMBool Value) {
  }
void
LLVMPassManagerBuilderUseInlinerWithThreshold(LLVMPassManagerBuilderRef PMB,
                                              unsigned Threshold) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->Inliner = createFunctionInliningPass(Threshold);
}
void
LLVMPassManagerBuilderPopulateFunctionPassManager(LLVMPassManagerBuilderRef PMB,
                                                  LLVMPassManagerRef PM) {
  PassManagerBuilder *Builder = unwrap(PMB);
  legacy::FunctionPassManager *FPM = unwrap<legacy::FunctionPassManager>(PM);
  Builder->populateFunctionPassManager(*FPM);
}
void
LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef PMB,
                                                LLVMPassManagerRef PM) {
  PassManagerBuilder *Builder = unwrap(PMB);
  legacy::PassManagerBase *MPM = unwrap(PM);
  Builder->populateModulePassManager(*MPM);
}