<commit_before>//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "ModelBuilder/ModelRunner.h"

#include "llvm/Support/TargetSelect.h"
#include "mlir/Conversion/AffineToStandard/AffineToStandard.h"
#include "mlir/Conversion/GPUToSPIRV/GPUToSPIRVPass.h"
#include "mlir/Conversion/GPUToVulkan/ConvertGPUToVulkanPass.h"
#include "mlir/Conversion/LLVMCommon/LoweringOptions.h"
#include "mlir/Conversion/LinalgToLLVM/LinalgToLLVM.h"
#include "mlir/Conversion/SCFToStandard/SCFToStandard.h"
#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h"
#include "mlir/Conversion/StandardToSPIRV/StandardToSPIRVPass.h"
#include "mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h"
#include "mlir/Conversion/VectorToSCF/VectorToSCF.h"
#include "mlir/Dialect/GPU/Passes.h"
#include "mlir/Dialect/Linalg/Passes.h"
#include "mlir/Dialect/MemRef/Transforms/Passes.h"
#include "mlir/Dialect/SPIRV/IR/SPIRVOps.h"
#include "mlir/Dialect/SPIRV/Transforms/Passes.h"
#include "mlir/ExecutionEngine/ExecutionEngine.h"
#include "mlir/ExecutionEngine/OptUtils.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
#include "mlir/Transforms/Passes.h"

static llvm::cl::opt<bool> mlirDebug(
    "mlir-debug", llvm::cl::desc("Single thread and print-ir-after-all"),
    llvm::cl::init(false));

struct LLVMInitializer {
  LLVMInitializer() {
    llvm::InitializeNativeTarget();
    llvm::InitializeNativeTargetAsmPrinter();
  }
};
static LLVMInitializer initializer;

namespace llvm {
extern Pass* createLowerMatrixIntrinsicsPass();
}  // end namespace llvm

void mlir::ModelRunner::compile(
    CompilationOptions compilationOptions,
    llvm::ArrayRef<const std::string> runtime,
    llvm::ArrayRef<std::pair<std::string, void*>> extra_symbols) {
  if (target == Target::CPUTarget) {
    // Lower vector operations progressively into more elementary
    // vector operations before running the regular compiler passes.
    mlir::OwningRewritePatternList patterns(module->getContext());
    mlir::vector::populateVectorContractLoweringPatterns(
        patterns, compilationOptions.vectorTransformsOptions);
    mlir::vector::populateVectorTransposeLoweringPatterns(
        patterns, compilationOptions.vectorTransformsOptions);
    (void)mlir::applyPatternsAndFoldGreedily(*module, std::move(patterns));
  }
  runLoweringPass(compilationOptions.loweringPasses
                      ? compilationOptions.loweringPasses
                      : getDefaultMLIRPassBuilder());

  // Make sure the execution engine runs LLVM passes for the specified
  // optimization level.
  auto tmBuilderOrError = llvm::orc::JITTargetMachineBuilder::detectHost();
  if (!tmBuilderOrError) {
    llvm::errs() << tmBuilderOrError.takeError() << "\n";
    return;
  }
  auto t = tmBuilderOrError->getTargetTriple().getTriple();
  auto tmOrError = tmBuilderOrError->createTargetMachine();
  if (!tmOrError) {
    llvm::errs() << tmOrError.takeError() << "\n";
    return;
  }
  targetMachine = std::move(tmOrError.get());
  SmallVector<const llvm::PassInfo*, 4> llvmPasses;
  if (target == Target::CPUTarget) {
    // TODO(ntv): Looking up the pass by name fails quite surprisingly. Just
    // build the pass to get its ID to look up the PassInfo.
    std::unique_ptr<llvm::Pass> owningLowerMatrixIntrinsicsPass(
        llvm::createLowerMatrixIntrinsicsPass());
    const llvm::PassInfo* lowerMatrixIntrinsics = llvm::Pass::lookupPassInfo(
        owningLowerMatrixIntrinsicsPass->getPassID());
    assert(lowerMatrixIntrinsics);
    llvmPasses.push_back(lowerMatrixIntrinsics);
  }
  auto transformer = mlir::makeLLVMPassesTransformer(
      llvmPasses, compilationOptions.llvmOptLevel, targetMachine.get(),
      /*optPassesInsertPos=*/0);

  // Pass in runtime support library when specified.
  SmallVector<StringRef, 4> libs(runtime.begin(), runtime.end());

  // Obtain the execution engine.
  auto created = mlir::ExecutionEngine::create(
      *module, /*llvmModuleBuilder=*/nullptr, transformer,
      static_cast<llvm::CodeGenOpt::Level>(compilationOptions.llcOptLevel),
      libs,
      /*enableObjectCache=*/true,
      /*enableGDBNotificationListener=*/false);
  llvm::handleAllErrors(created.takeError(), [](const llvm::ErrorInfoBase& b) {
    b.log(llvm::errs());
    assert(false);
  });
  engine = std::move(*created);

  // Define any extra symbols so they're available at runtime.
  auto symbolRegisterer =
      [&extra_symbols](llvm::orc::MangleAndInterner interner) {
        llvm::orc::SymbolMap symbolMap;
        for (auto& symbol : extra_symbols) {
          const std::string& name = symbol.first;
          void* function_pointer = symbol.second;
          symbolMap[interner(name)] =
              llvm::JITEvaluatedSymbol::fromPointer(function_pointer);
        }
        return symbolMap;
      };
  engine->registerSymbols(symbolRegisterer);
}

static void addVulkanLoweringPass(mlir::PassManager& manager) {
  manager.addPass(mlir::createGpuKernelOutliningPass());
  manager.addPass(mlir::memref::createFoldSubViewOpsPass());
  manager.addPass(mlir::createConvertGPUToSPIRVPass());
  mlir::OpPassManager& modulePM = manager.nest<mlir::spirv::ModuleOp>();
  modulePM.addPass(mlir::spirv::createLowerABIAttributesPass());
  modulePM.addPass(mlir::spirv::createUpdateVersionCapabilityExtensionPass());
  manager.addPass(mlir::createConvertGpuLaunchFuncToVulkanLaunchFuncPass());
  mlir::LowerToLLVMOptions llvmOptions(manager.getContext());
  llvmOptions.emitCWrappers = true;
  manager.addPass(createLowerToLLVMPass(llvmOptions));
  manager.addPass(mlir::createConvertVulkanLaunchFuncToVulkanCallsPass());
}

static void addCPULoweringPass(mlir::PassManager& manager) {
  // Set up compiler passes.
  manager.addNestedPass<mlir::FuncOp>(mlir::createConvertVectorToSCFPass());
  manager.addNestedPass<mlir::FuncOp>(mlir::createConvertLinalgToLoopsPass());
  manager.addPass(mlir::createConvertLinalgToLLVMPass());
  manager.addPass(mlir::createConvertLinalgToLoopsPass());
  manager.addPass(mlir::createLowerAffinePass());
  manager.addPass(mlir::createLowerToCFGPass());
  manager.addPass(mlir::createConvertVectorToLLVMPass());
  manager.addPass(mlir::createLowerToLLVMPass());
}

std::function<void(mlir::PassManager&)>
mlir::ModelRunner::getDefaultMLIRPassBuilder() {
  if (target == Target::CPUTarget) {
    return addCPULoweringPass;
  } else {
    assert(target == Target::GPUTarget);
    return addVulkanLoweringPass;
  }
}

void mlir::ModelRunner::runLoweringPass(
    std::function<void(mlir::PassManager&)> passBuilder) {
  PassManager manager(module->getContext(),
                      mlir::OpPassManager::Nesting::Implicit);
  if (mlirDebug) {
    manager.getContext()->disableMultithreading();
    manager.enableIRPrinting([](Pass*, Operation*) { return true; },
                             [](Pass*, Operation*) { return true; }, true, true,
                             /*printAfterOnlyOnFailure=*/false, llvm::errs());
  }
  passBuilder(manager);
  if (failed(manager.run(*module))) {
    llvm::errs() << "conversion to the LLVM IR dialect failed\n";<commit_msg>Add -reconcile-unrealized-casts pass to ModelRunner<commit_after>//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "ModelBuilder/ModelRunner.h"

#include "llvm/Support/TargetSelect.h"
#include "mlir/Conversion/AffineToStandard/AffineToStandard.h"
#include "mlir/Conversion/GPUToSPIRV/GPUToSPIRVPass.h"
#include "mlir/Conversion/GPUToVulkan/ConvertGPUToVulkanPass.h"
#include "mlir/Conversion/LLVMCommon/LoweringOptions.h"
#include "mlir/Conversion/LinalgToLLVM/LinalgToLLVM.h"
#include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
#include "mlir/Conversion/SCFToStandard/SCFToStandard.h"
#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h"
#include "mlir/Conversion/StandardToSPIRV/StandardToSPIRVPass.h"
#include "mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h"
#include "mlir/Conversion/VectorToSCF/VectorToSCF.h"
#include "mlir/Dialect/GPU/Passes.h"
#include "mlir/Dialect/Linalg/Passes.h"
#include "mlir/Dialect/MemRef/Transforms/Passes.h"
#include "mlir/Dialect/SPIRV/IR/SPIRVOps.h"
#include "mlir/Dialect/SPIRV/Transforms/Passes.h"
#include "mlir/ExecutionEngine/ExecutionEngine.h"
#include "mlir/ExecutionEngine/OptUtils.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
#include "mlir/Transforms/Passes.h"

static llvm::cl::opt<bool> mlirDebug(
    "mlir-debug", llvm::cl::desc("Single thread and print-ir-after-all"),
    llvm::cl::init(false));

struct LLVMInitializer {
  LLVMInitializer() {
    llvm::InitializeNativeTarget();
    llvm::InitializeNativeTargetAsmPrinter();
  }
};
static LLVMInitializer initializer;

namespace llvm {
extern Pass* createLowerMatrixIntrinsicsPass();
}  // end namespace llvm

void mlir::ModelRunner::compile(
    CompilationOptions compilationOptions,
    llvm::ArrayRef<const std::string> runtime,
    llvm::ArrayRef<std::pair<std::string, void*>> extra_symbols) {
  if (target == Target::CPUTarget) {
    // Lower vector operations progressively into more elementary
    // vector operations before running the regular compiler passes.
    mlir::OwningRewritePatternList patterns(module->getContext());
    mlir::vector::populateVectorContractLoweringPatterns(
        patterns, compilationOptions.vectorTransformsOptions);
    mlir::vector::populateVectorTransposeLoweringPatterns(
        patterns, compilationOptions.vectorTransformsOptions);
    (void)mlir::applyPatternsAndFoldGreedily(*module, std::move(patterns));
  }
  runLoweringPass(compilationOptions.loweringPasses
                      ? compilationOptions.loweringPasses
                      : getDefaultMLIRPassBuilder());

  // Make sure the execution engine runs LLVM passes for the specified
  // optimization level.
  auto tmBuilderOrError = llvm::orc::JITTargetMachineBuilder::detectHost();
  if (!tmBuilderOrError) {
    llvm::errs() << tmBuilderOrError.takeError() << "\n";
    return;
  }
  auto t = tmBuilderOrError->getTargetTriple().getTriple();
  auto tmOrError = tmBuilderOrError->createTargetMachine();
  if (!tmOrError) {
    llvm::errs() << tmOrError.takeError() << "\n";
    return;
  }
  targetMachine = std::move(tmOrError.get());
  SmallVector<const llvm::PassInfo*, 4> llvmPasses;
  if (target == Target::CPUTarget) {
    // TODO(ntv): Looking up the pass by name fails quite surprisingly. Just
    // build the pass to get its ID to look up the PassInfo.
    std::unique_ptr<llvm::Pass> owningLowerMatrixIntrinsicsPass(
        llvm::createLowerMatrixIntrinsicsPass());
    const llvm::PassInfo* lowerMatrixIntrinsics = llvm::Pass::lookupPassInfo(
        owningLowerMatrixIntrinsicsPass->getPassID());
    assert(lowerMatrixIntrinsics);
    llvmPasses.push_back(lowerMatrixIntrinsics);
  }
  auto transformer = mlir::makeLLVMPassesTransformer(
      llvmPasses, compilationOptions.llvmOptLevel, targetMachine.get(),
      /*optPassesInsertPos=*/0);

  // Pass in runtime support library when specified.
  SmallVector<StringRef, 4> libs(runtime.begin(), runtime.end());

  // Obtain the execution engine.
  auto created = mlir::ExecutionEngine::create(
      *module, /*llvmModuleBuilder=*/nullptr, transformer,
      static_cast<llvm::CodeGenOpt::Level>(compilationOptions.llcOptLevel),
      libs,
      /*enableObjectCache=*/true,
      /*enableGDBNotificationListener=*/false);
  llvm::handleAllErrors(created.takeError(), [](const llvm::ErrorInfoBase& b) {
    b.log(llvm::errs());
    assert(false);
  });
  engine = std::move(*created);

  // Define any extra symbols so they're available at runtime.
  auto symbolRegisterer =
      [&extra_symbols](llvm::orc::MangleAndInterner interner) {
        llvm::orc::SymbolMap symbolMap;
        for (auto& symbol : extra_symbols) {
          const std::string& name = symbol.first;
          void* function_pointer = symbol.second;
          symbolMap[interner(name)] =
              llvm::JITEvaluatedSymbol::fromPointer(function_pointer);
        }
        return symbolMap;
      };
  engine->registerSymbols(symbolRegisterer);
}

static void addVulkanLoweringPass(mlir::PassManager& manager) {
  manager.addPass(mlir::createGpuKernelOutliningPass());
  manager.addPass(mlir::memref::createFoldSubViewOpsPass());
  manager.addPass(mlir::createConvertGPUToSPIRVPass());
  mlir::OpPassManager& modulePM = manager.nest<mlir::spirv::ModuleOp>();
  modulePM.addPass(mlir::spirv::createLowerABIAttributesPass());
  modulePM.addPass(mlir::spirv::createUpdateVersionCapabilityExtensionPass());
  manager.addPass(mlir::createConvertGpuLaunchFuncToVulkanLaunchFuncPass());
  mlir::LowerToLLVMOptions llvmOptions(manager.getContext());
  llvmOptions.emitCWrappers = true;
  manager.addPass(createLowerToLLVMPass(llvmOptions));
  manager.addPass(mlir::createReconcileUnrealizedCastsPass());
  manager.addPass(mlir::createConvertVulkanLaunchFuncToVulkanCallsPass());
}

static void addCPULoweringPass(mlir::PassManager& manager) {
  // Set up compiler passes.
  manager.addNestedPass<mlir::FuncOp>(mlir::createConvertVectorToSCFPass());
  manager.addNestedPass<mlir::FuncOp>(mlir::createConvertLinalgToLoopsPass());
  manager.addPass(mlir::createConvertLinalgToLLVMPass());
  manager.addPass(mlir::createConvertLinalgToLoopsPass());
  manager.addPass(mlir::createLowerAffinePass());
  manager.addPass(mlir::createLowerToCFGPass());
  manager.addPass(mlir::createConvertVectorToLLVMPass());
  manager.addPass(mlir::createLowerToLLVMPass());
  manager.addPass(mlir::createReconcileUnrealizedCastsPass());
}

std::function<void(mlir::PassManager&)>
mlir::ModelRunner::getDefaultMLIRPassBuilder() {
  if (target == Target::CPUTarget) {
    return addCPULoweringPass;
  } else {
    assert(target == Target::GPUTarget);
    return addVulkanLoweringPass;
  }
}

void mlir::ModelRunner::runLoweringPass(
    std::function<void(mlir::PassManager&)> passBuilder) {
  PassManager manager(module->getContext(),
                      mlir::OpPassManager::Nesting::Implicit);
  if (mlirDebug) {
    manager.getContext()->disableMultithreading();
    manager.enableIRPrinting([](Pass*, Operation*) { return true; },
                             [](Pass*, Operation*) { return true; }, true, true,
                             /*printAfterOnlyOnFailure=*/false, llvm::errs());
  }
  passBuilder(manager);
  if (failed(manager.run(*module))) {
    llvm::errs() << "conversion to the LLVM IR dialect failed\n";
{'fraction_non_alphanumeric': 0.14915787404154926, 'fraction_numerical': 0.0009174913166000394, 'mean_word_length': 4.635155096011816, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 43, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2984580', 'n_tokens_mistral': 4744, 'n_tokens_neox': 4758, 'n_words': 735}