From 8f4f26ba5bd04f7b335836021e5e63b4236c0305 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Fri, 9 Sep 2022 14:20:27 -0500 Subject: [PATCH] [MLGO] ML Regalloc Priority Advisor The bulk of the implementation is common between 'release' mode (==AOT-ed model) and 'development' mode (for training), the main difference is that in development mode, we may also log features (for training logs), inject scoring information and then produce the log file. Differential Revision: https://reviews.llvm.org/D133616 --- .../models/gen-regalloc-priority-test-model.py | 95 ++++++ llvm/lib/CodeGen/CMakeLists.txt | 1 + llvm/lib/CodeGen/MLRegallocPriorityAdvisor.cpp | 335 +++++++++++++++++++ llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp | 8 +- .../MLRegalloc/Inputs/reference-prio-log-noml.txt | 361 +++++++++++++++++++++ .../CodeGen/MLRegalloc/dev-mode-prio-logging.ll | 29 ++ 6 files changed, 827 insertions(+), 2 deletions(-) create mode 100644 llvm/lib/Analysis/models/gen-regalloc-priority-test-model.py create mode 100644 llvm/lib/CodeGen/MLRegallocPriorityAdvisor.cpp create mode 100644 llvm/test/CodeGen/MLRegalloc/Inputs/reference-prio-log-noml.txt create mode 100644 llvm/test/CodeGen/MLRegalloc/dev-mode-prio-logging.ll diff --git a/llvm/lib/Analysis/models/gen-regalloc-priority-test-model.py b/llvm/lib/Analysis/models/gen-regalloc-priority-test-model.py new file mode 100644 index 0000000..81de2c7 --- /dev/null +++ b/llvm/lib/Analysis/models/gen-regalloc-priority-test-model.py @@ -0,0 +1,95 @@ +"""Generate a mock model for LLVM tests for Register Allocation. +The generated model is not a neural net - it is just a tf.function with the +correct input and output parameters. +""" +## By construction, the mock model will always output the first liverange that can be evicted. + +import os +import sys +import tensorflow as tf +POLICY_DECISION_LABEL = 'priority' +POLICY_OUTPUT_SPEC = """ +[ + { + "logging_name": "priority", + "tensor_spec": { + "name": "StatefulPartitionedCall", + "port": 0, + "type": "float", + "shape": [ + 1 + ] + } + } +] +""" +PER_LIVEINTERVAL_INT64_FEATURE_LIST = [ + 'li_size', 'stage' +] +PER_LIVEINTERVAL_FLOAT32_FEATURE_LIST = ['weight' +] +PER_LIVEINTERVAL_FEATURE_LIST = PER_LIVEINTERVAL_FLOAT32_FEATURE_LIST + \ + PER_LIVEINTERVAL_INT64_FEATURE_LIST +CONTEXT_FEATURE_LIST = ('discount', 'reward', 'step_type') + + +def get_input_signature(): + """Returns (time_step_spec, action_spec) for LLVM register allocation.""" + inputs = dict( + (key, tf.TensorSpec(dtype=tf.int64, shape=(), name=key)) + for key in PER_LIVEINTERVAL_INT64_FEATURE_LIST) + inputs.update( + dict((key, + tf.TensorSpec(dtype=tf.float32, shape=(), name=key)) + for key in PER_LIVEINTERVAL_FLOAT32_FEATURE_LIST)) + inputs.update( + dict((key, tf.TensorSpec(dtype=tf.float32, shape=(), name=key)) + for key in ['discount', 'reward'])) + inputs.update( + dict((key, tf.TensorSpec(dtype=tf.int32, shape=(), name=key)) + for key in ['step_type'])) + return inputs + + +def get_output_spec_path(path): + return os.path.join(path, 'output_spec.json') + + +def build_mock_model(path): + """Build and save the mock model with the given signature.""" + module = tf.Module() + # We have to set this useless variable in order for the TF C API to correctly + # intake it + module.var = tf.Variable(0, dtype=tf.float32) + + def action(*inputs): + s1 = tf.reduce_sum([ + tf.cast(inputs[0][key], tf.float32) for key in PER_LIVEINTERVAL_FEATURE_LIST + ], + axis=0) + s2 = tf.reduce_sum( + [tf.cast(inputs[0][key], tf.float32) for key in CONTEXT_FEATURE_LIST]) + # Add a large number so s won't be 0. + s = s1 + s2 + result = s + module.var + return {POLICY_DECISION_LABEL: result} + module.action = tf.function()(action) + action = { + 'action': module.action.get_concrete_function(get_input_signature()) + } + + tf.saved_model.save(module, path, signatures=action) + output_spec_path = get_output_spec_path(path) + with open(output_spec_path, 'w') as f: + print(f'Writing output spec to {output_spec_path}.') + f.write(POLICY_OUTPUT_SPEC) + + +def main(argv): + assert len(argv) == 2 + model_path = argv[1] + build_mock_model(model_path) + + +if __name__ == '__main__': + main(sys.argv) diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt index afa3704..ce14e1d 100644 --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -143,6 +143,7 @@ add_llvm_component_library(LLVMCodeGen MIRSampleProfile.cpp MIRYamlMapping.cpp MLRegallocEvictAdvisor.cpp + MLRegallocPriorityAdvisor.cpp ModuloSchedule.cpp MultiHazardRecognizer.cpp PatchableFunction.cpp diff --git a/llvm/lib/CodeGen/MLRegallocPriorityAdvisor.cpp b/llvm/lib/CodeGen/MLRegallocPriorityAdvisor.cpp new file mode 100644 index 0000000..cda1e4e --- /dev/null +++ b/llvm/lib/CodeGen/MLRegallocPriorityAdvisor.cpp @@ -0,0 +1,335 @@ +//===- MLRegAllocPriorityAdvisor.cpp - ML priority advisor-----------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Implementation of the ML priority advisor and reward injection pass +// +//===----------------------------------------------------------------------===// + +#include "AllocationOrder.h" +#include "RegAllocGreedy.h" +#include "RegAllocPriorityAdvisor.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/MLModelRunner.h" +#include "llvm/Analysis/ReleaseModeModelRunner.h" +#include "llvm/Analysis/TensorSpec.h" +#include "llvm/CodeGen/CalcSpillWeights.h" +#include "llvm/CodeGen/LiveRegMatrix.h" +#include "llvm/CodeGen/MachineBlockFrequencyInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/RegisterClassInfo.h" +#include "llvm/CodeGen/SlotIndexes.h" +#include "llvm/CodeGen/VirtRegMap.h" +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" +#include "llvm/PassRegistry.h" +#include "llvm/Support/CommandLine.h" + +#if defined(LLVM_HAVE_TF_API) +#include "llvm/Analysis/ModelUnderTrainingRunner.h" +#include "llvm/Analysis/NoInferenceModelRunner.h" +#include "llvm/Analysis/Utils/TrainingLogger.h" +#endif + +using namespace llvm; + +// Options that only make sense in development mode +#ifdef LLVM_HAVE_TF_API +#include "RegAllocScore.h" +#include "llvm/Analysis/Utils/TFUtils.h" + +static cl::opt TrainingLog( + "regalloc-priority-training-log", cl::Hidden, + cl::desc("Training log for the register allocator priority model")); + +static cl::opt ModelUnderTraining( + "regalloc-priority-model", cl::Hidden, + cl::desc("The model being trained for register allocation priority")); + +#endif // #ifdef LLVM_HAVE_TF_API + +namespace llvm { + +static const std::vector PerLiveRangeShape{1}; + +#define RA_PRIORITY_FEATURES_LIST(M) \ + M(int64_t, li_size, PerLiveRangeShape, "size") \ + M(int64_t, stage, PerLiveRangeShape, "stage") \ + M(float, weight, PerLiveRangeShape, "weight") + +#define DecisionName "priority" + +// Named features index. +enum FeatureIDs { +#define _FEATURE_IDX(_, name, __, ___) name, + RA_PRIORITY_FEATURES_LIST(_FEATURE_IDX) +#undef _FEATURE_IDX + FeatureCount +}; + +class MLPriorityAdvisor : public RegAllocPriorityAdvisor { +public: + MLPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA, + SlotIndexes *const Indexes, MLModelRunner *Runner); + +protected: + const RegAllocPriorityAdvisor &getDefaultAdvisor() const { + return static_cast(DefaultAdvisor); + } + + // The assumption is that if the Runner could not be constructed, we emit-ed + // error, and we shouldn't be asking for it here. + const MLModelRunner &getRunner() const { return *Runner; } + float getPriorityImpl(const LiveInterval &LI) const; + unsigned getPriority(const LiveInterval &LI) const override; + +private: + const DefaultPriorityAdvisor DefaultAdvisor; + MLModelRunner *const Runner; +}; + +#define _DECL_FEATURES(type, name, shape, _) \ + TensorSpec::createSpec(#name, shape), + +static const std::vector InputFeatures{ + {RA_PRIORITY_FEATURES_LIST(_DECL_FEATURES)}, +}; +#undef _DECL_FEATURES + +// =================================== +// Release (AOT) - specifics +// =================================== +class ReleaseModePriorityAdvisorAnalysis final + : public RegAllocPriorityAdvisorAnalysis { +public: + ReleaseModePriorityAdvisorAnalysis() + : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Release) {} + // support for isa<> and dyn_cast. + static bool classof(const RegAllocPriorityAdvisorAnalysis *R) { + return R->getAdvisorMode() == AdvisorMode::Release; + } + +private: + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + AU.addRequired(); + RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU); + } + + std::unique_ptr + getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override { + if (!Runner) + Runner = std::make_unique>( + MF.getFunction().getContext(), InputFeatures, DecisionName); + return std::make_unique( + MF, RA, &getAnalysis(), Runner.get()); + } + std::unique_ptr> Runner; +}; + +// =================================== +// Development mode-specifics +// =================================== +// +// Features we log +#ifdef LLVM_HAVE_TF_API + +static const TensorSpec Output = + TensorSpec::createSpec(DecisionName, {1}); +static const TensorSpec Reward = TensorSpec::createSpec("reward", {1}); + +#define _DECL_TRAIN_FEATURES(type, name, shape, _) \ + TensorSpec::createSpec(std::string("action_") + #name, shape), + +static const std::vector TrainingInputFeatures{ + {RA_PRIORITY_FEATURES_LIST(_DECL_TRAIN_FEATURES) + TensorSpec::createSpec("action_discount", {1}), + TensorSpec::createSpec("action_step_type", {1}), + TensorSpec::createSpec("action_reward", {1})}}; +#undef _DECL_TRAIN_FEATURES + +class DevelopmentModePriorityAdvisor : public MLPriorityAdvisor { +public: + DevelopmentModePriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA, + SlotIndexes *const Indexes, + MLModelRunner *Runner, Logger *Log) + : MLPriorityAdvisor(MF, RA, Indexes, Runner), Log(Log) {} + +private: + unsigned getPriority(const LiveInterval &LI) const override; + Logger *const Log; +}; + +class DevelopmentModePriorityAdvisorAnalysis final + : public RegAllocPriorityAdvisorAnalysis { +public: + DevelopmentModePriorityAdvisorAnalysis() + : RegAllocPriorityAdvisorAnalysis(AdvisorMode::Development) {} + // support for isa<> and dyn_cast. + static bool classof(const RegAllocPriorityAdvisorAnalysis *R) { + return R->getAdvisorMode() == AdvisorMode::Development; + } + + /// get the logger for the given function, or nullptr if we didn't collect + /// one. This is used to inject the score by the RegAllocScoring pass. + Logger *getLogger(const MachineFunction &MF) const { + auto I = LogMap.find(MF.getName()); + if (I == LogMap.end()) + return nullptr; + return I->second.get(); + } + + void logRewardIfNeeded(const MachineFunction &MF, + llvm::function_ref GetReward) override { + if (auto *Log = this->getLogger(MF)) + Log->logFloatFinalReward(GetReward()); + } + +private: + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + AU.addRequired(); + RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU); + } + + // Save all the logs (when requested). + bool doFinalization(Module &M) override { + if (TrainingLog.empty()) + return false; + std::error_code EC; + auto OS = std::make_unique(TrainingLog, EC); + if (EC) { + M.getContext().emitError(EC.message() + ":" + TrainingLog); + return false; + } + Logger::flushLogs(*OS, LogMap); + return false; + } + + std::unique_ptr + getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override { + + LLVMContext &Ctx = MF.getFunction().getContext(); + if (ModelUnderTraining.empty() && TrainingLog.empty()) { + Ctx.emitError("Regalloc development mode should be requested with at " + "least logging enabled and/or a training model"); + return nullptr; + } + if (!Runner) { + if (ModelUnderTraining.empty()) + Runner = std::make_unique(Ctx, InputFeatures); + else + Runner = ModelUnderTrainingRunner::createAndEnsureValid( + Ctx, ModelUnderTraining, DecisionName, TrainingInputFeatures); + if (!Runner) { + Ctx.emitError("Regalloc: could not set up the model runner"); + return nullptr; + } + } + + Logger *Log = nullptr; + if (!TrainingLog.empty()) { + std::vector LFS; + for (const auto &FS : InputFeatures) + LFS.push_back({FS, None}); + if (auto *MUTR = dyn_cast(Runner.get())) + if (MUTR->outputLoggedFeatureSpecs().size() > 1) + append_range(LFS, drop_begin(MUTR->outputLoggedFeatureSpecs())); + // We always log the output; in particular, if we're not evaluating, we + // don't have an output spec json file. That's why we handle the + // 'normal' output separately. + LFS.push_back({Output, None}); + auto I = LogMap.insert(std::make_pair( + MF.getFunction().getName(), + std::make_unique(LFS, Reward, /*IncludeReward*/ true))); + assert(I.second); + Log = I.first->second.get(); + } + + return std::make_unique( + MF, RA, &getAnalysis(), Runner.get(), Log); + } + + std::unique_ptr Runner; + StringMap> LogMap; +}; +#endif //#ifdef LLVM_HAVE_TF_API + +} // namespace llvm + +RegAllocPriorityAdvisorAnalysis *llvm::createReleaseModePriorityAdvisor() { + return new ReleaseModePriorityAdvisorAnalysis(); +} + +MLPriorityAdvisor::MLPriorityAdvisor(const MachineFunction &MF, + const RAGreedy &RA, + SlotIndexes *const Indexes, + MLModelRunner *Runner) + : RegAllocPriorityAdvisor(MF, RA, Indexes), DefaultAdvisor(MF, RA, Indexes), + Runner(std::move(Runner)) { + assert(this->Runner); +} + +float MLPriorityAdvisor::getPriorityImpl(const LiveInterval &LI) const { + const unsigned Size = LI.getSize(); + LiveRangeStage Stage = RA.getExtraInfo().getStage(LI); + + *Runner->getTensor(0) = static_cast(Size); + *Runner->getTensor(1) = static_cast(Stage); + *Runner->getTensor(2) = static_cast(LI.weight()); + + return Runner->evaluate(); +} + +unsigned MLPriorityAdvisor::getPriority(const LiveInterval &LI) const { + return static_cast(getPriorityImpl(LI)); +} + +#ifdef LLVM_HAVE_TF_API +RegAllocPriorityAdvisorAnalysis *llvm::createDevelopmentModePriorityAdvisor() { + return new DevelopmentModePriorityAdvisorAnalysis(); +} + +unsigned +DevelopmentModePriorityAdvisor::getPriority(const LiveInterval &LI) const { + double Prio = 0; + + if (isa(getRunner())) { + Prio = MLPriorityAdvisor::getPriorityImpl(LI); + } else { + Prio = getDefaultAdvisor().getPriority(LI); + } + + if (TrainingLog.empty()) + return Prio; + + size_t CurrentFeature = 0; + for (; CurrentFeature < InputFeatures.size(); ++CurrentFeature) { + Log->logSpecifiedTensorValue( + CurrentFeature, reinterpret_cast( + getRunner().getTensorUntyped(CurrentFeature))); + } + + if (auto *MUTR = dyn_cast(&getRunner())) { + for (size_t I = 1; I < MUTR->outputLoggedFeatureSpecs().size(); + ++I, ++CurrentFeature) + Log->logSpecifiedTensorValue( + CurrentFeature, + reinterpret_cast( + MUTR->lastEvaluationResult()->getUntypedTensorValue(I))); + } + + float Ret = static_cast(Prio); + Log->logFloatValue(CurrentFeature, &Ret); + + return static_cast(Prio); +} + +#endif // #ifdef LLVM_HAVE_TF_API diff --git a/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp b/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp index 5ace3dd..88fd47e 100644 --- a/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp +++ b/llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp @@ -76,10 +76,14 @@ template <> Pass *llvm::callDefaultCtor() { Ret = new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ false); break; case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development: - // TODO: add implementation +#if defined(LLVM_HAVE_TF_API) + Ret = createDevelopmentModePriorityAdvisor(); +#endif break; case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Release: - // TODO: add implementation +#if defined(LLVM_HAVE_TF_AOT_REGALLOCPRIORITYMODEL) + Ret = createReleaseModePriorityAdvisor(); +#endif break; } if (Ret) diff --git a/llvm/test/CodeGen/MLRegalloc/Inputs/reference-prio-log-noml.txt b/llvm/test/CodeGen/MLRegalloc/Inputs/reference-prio-log-noml.txt new file mode 100644 index 0000000..2714802 --- /dev/null +++ b/llvm/test/CodeGen/MLRegalloc/Inputs/reference-prio-log-noml.txt @@ -0,0 +1,361 @@ +fields { + key: "SyFgets" + value { + string_value: "feature_lists { + feature_list { + key: \"li_size\" value { + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } } } + feature_list { + key: \"priority\" value { + feature { float_list { value: 2.68435814e+09 } } + feature { float_list { value: 2.68435814e+09 } } + feature { float_list { value: 2.68435866e+09 } } + feature { float_list { value: 2.68435789e+09 } } + feature { float_list { value: 3.75810074e+09 } } + feature { float_list { value: 3.7580969e+09 } } + feature { float_list { value: 2.14748518e+09 } } + feature { float_list { value: 2.14748493e+09 } } + feature { float_list { value: 2.68435814e+09 } } + feature { float_list { value: 2.14748493e+09 } } + feature { float_list { value: 2.14748493e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.68435763e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.14748467e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.68435763e+09 } } + feature { float_list { value: 2.68435763e+09 } } + feature { float_list { value: 2.1474839e+09 } } + feature { float_list { value: 2.1474839e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.1474839e+09 } } + feature { float_list { value: 3.22122547e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.14748365e+09 } } + feature { float_list { value: 2.14748493e+09 } } + feature { float_list { value: 2.14748493e+09 } } + feature { float_list { value: 2.68435814e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.68435584e+09 } } + feature { float_list { value: 2.68435482e+09 } } + feature { float_list { value: 2.68435482e+09 } } + feature { float_list { value: 2.68435763e+09 } } + feature { float_list { value: 2.68435584e+09 } } + feature { float_list { value: 2.14748365e+09 } } + feature { float_list { value: 3.75810074e+09 } } + feature { float_list { value: 2.68435814e+09 } } + feature { float_list { value: 3584 } } + feature { float_list { value: 2.68435814e+09 } } + feature { float_list { value: 3550 } } + feature { float_list { value: 2.68435814e+09 } } + feature { float_list { value: 3534 } } + feature { float_list { value: 2974 } } + feature { float_list { value: 2958 } } + feature { float_list { value: 3.75809946e+09 } } + feature { float_list { value: 2.68435866e+09 } } + feature { float_list { value: 3998 } } + feature { float_list { value: 3.75810074e+09 } } + feature { float_list { value: 4336 } } + feature { float_list { value: 2.6843584e+09 } } + feature { float_list { value: 3.75809664e+09 } } + feature { float_list { value: 2.68435482e+09 } } + feature { float_list { value: 2.68435482e+09 } } + feature { float_list { value: 2.68435814e+09 } } + feature { float_list { value: 2.68435482e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.68435814e+09 } } + feature { float_list { value: 2.14748493e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.68435814e+09 } } + feature { float_list { value: 2.14748493e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.68435456e+09 } } + feature { float_list { value: 2.68435456e+09 } } } } + feature_list { + key: \"reward\" value { + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 36.6412773 } } } } + feature_list { + key: \"stage\" value { + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } + feature { int64_list { value: 0 } } } } + feature_list { + key: \"weight\" value { + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } + feature { float_list { value: 0 } } } } } " + } +} diff --git a/llvm/test/CodeGen/MLRegalloc/dev-mode-prio-logging.ll b/llvm/test/CodeGen/MLRegalloc/dev-mode-prio-logging.ll new file mode 100644 index 0000000..e8b05d5 --- /dev/null +++ b/llvm/test/CodeGen/MLRegalloc/dev-mode-prio-logging.ll @@ -0,0 +1,29 @@ +; REQUIRES: have_tf_api +; REQUIRES: x86_64-linux +; +; Check that we log correctly, both with a learned policy, and the default policy +; +; RUN: llc -mtriple=x86_64-linux-unknown -regalloc=greedy -regalloc-enable-priority-advisor=development \ +; RUN: -regalloc-priority-training-log=%t1 -tfutils-text-log < %S/Inputs/input.ll +; RUN: sed -i 's/ \+/ /g' %t1 +; RUN: sed -i 's/\\n key:/\n key:/g' %t1 +; RUN: sed -i 's/\\n feature/\n feature/g' %t1 +; RUN: sed -i 's/\\n/ /g' %t1 +; RUN: FileCheck --input-file %t1 %s --check-prefixes=CHECK,NOML +; RUN: diff %t1 %S/Inputs/reference-prio-log-noml.txt + +; RUN: rm -rf %t && mkdir %t +; RUN: %python %S/../../../lib/Analysis/models/gen-regalloc-priority-test-model.py %t +; RUN: llc -mtriple=x86_64-linux-unknown -regalloc=greedy -regalloc-enable-priority-advisor=development \ +; RUN: -regalloc-priority-training-log=%t2 -tfutils-text-log -regalloc-priority-model=%t < %S/Inputs/input.ll +; RUN: sed -i 's/ \+/ /g' %t2 +; RUN: sed -i 's/\\n key:/\n key:/g' %t2 +; RUN: sed -i 's/\\n feature/\n feature/g' %t2 +; RUN: sed -i 's/\\n/ /g' %t2 +; RUN: FileCheck --input-file %t2 %s --check-prefixes=CHECK,ML + +; CHECK-NOT: nan +; CHECK-LABEL: key: \"priority\" +; NOML-NEXT: feature { float_list { value: 2.68435814e+09 } } +; ML-NEXT: feature { float_list { value: 3551 } } +; CHECK-LABEL: key: \"reward\" -- 2.7.4