15ffd83dbSDimitry Andric //===- InlineModelFeatureMaps.h - common model runner defs ------*- C++ -*-===// 25ffd83dbSDimitry Andric // 35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65ffd83dbSDimitry Andric // 75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 85ffd83dbSDimitry Andric // 95ffd83dbSDimitry Andric 105ffd83dbSDimitry Andric #ifndef LLVM_ANALYSIS_INLINEMODELFEATUREMAPS_H 115ffd83dbSDimitry Andric #define LLVM_ANALYSIS_INLINEMODELFEATUREMAPS_H 125ffd83dbSDimitry Andric 1381ad6265SDimitry Andric #include "llvm/Analysis/TensorSpec.h" 1481ad6265SDimitry Andric 155ffd83dbSDimitry Andric #include <array> 165ffd83dbSDimitry Andric #include <vector> 175ffd83dbSDimitry Andric 185ffd83dbSDimitry Andric namespace llvm { 195ffd83dbSDimitry Andric 20fe6060f1SDimitry Andric // List of cost features. A "cost" feature is a summand of the heuristic-based 21fe6060f1SDimitry Andric // inline cost, and we define them separately to preserve the original heuristic 22fe6060f1SDimitry Andric // behavior. 23fe6060f1SDimitry Andric #define INLINE_COST_FEATURE_ITERATOR(M) \ 2406c3fb27SDimitry Andric M(int64_t, {1}, sroa_savings, \ 2506c3fb27SDimitry Andric "Savings from SROA (scalar replacement of aggregates)") \ 2606c3fb27SDimitry Andric M(int64_t, {1}, sroa_losses, \ 2706c3fb27SDimitry Andric "Losses from SROA (scalar replacement of aggregates)") \ 2806c3fb27SDimitry Andric M(int64_t, {1}, load_elimination, "Cost of load elimination in the call") \ 2906c3fb27SDimitry Andric M(int64_t, {1}, call_penalty, \ 3006c3fb27SDimitry Andric "Accumulation of penalty applied to call sites when inlining") \ 3106c3fb27SDimitry Andric M(int64_t, {1}, call_argument_setup, \ 3206c3fb27SDimitry Andric "Accumulation of call argument setup costs") \ 3306c3fb27SDimitry Andric M(int64_t, {1}, load_relative_intrinsic, \ 3406c3fb27SDimitry Andric "Accumulation of costs of loading relative intrinsics") \ 3506c3fb27SDimitry Andric M(int64_t, {1}, lowered_call_arg_setup, \ 3606c3fb27SDimitry Andric "Accumulation of cost of lowered call argument setups") \ 3706c3fb27SDimitry Andric M(int64_t, {1}, indirect_call_penalty, \ 3806c3fb27SDimitry Andric "Accumulation of costs for indirect calls") \ 3906c3fb27SDimitry Andric M(int64_t, {1}, jump_table_penalty, "Accumulation of costs for jump tables") \ 4006c3fb27SDimitry Andric M(int64_t, {1}, case_cluster_penalty, \ 4106c3fb27SDimitry Andric "Accumulation of costs for case clusters") \ 42*0fca6ea1SDimitry Andric M(int64_t, {1}, switch_default_dest_penalty, \ 43*0fca6ea1SDimitry Andric "Accumulation of costs for switch default destination") \ 4406c3fb27SDimitry Andric M(int64_t, {1}, switch_penalty, \ 4506c3fb27SDimitry Andric "Accumulation of costs for switch statements") \ 4606c3fb27SDimitry Andric M(int64_t, {1}, unsimplified_common_instructions, \ 4706c3fb27SDimitry Andric "Costs from unsimplified common instructions") \ 4806c3fb27SDimitry Andric M(int64_t, {1}, num_loops, "Number of loops in the caller") \ 4906c3fb27SDimitry Andric M(int64_t, {1}, dead_blocks, "Number of dead blocks in the caller") \ 5006c3fb27SDimitry Andric M(int64_t, {1}, simplified_instructions, \ 5106c3fb27SDimitry Andric "Number of simplified instructions") \ 5206c3fb27SDimitry Andric M(int64_t, {1}, constant_args, \ 5306c3fb27SDimitry Andric "Number of constant arguments in the call site") \ 5406c3fb27SDimitry Andric M(int64_t, {1}, constant_offset_ptr_args, \ 5506c3fb27SDimitry Andric "Number of constant offset pointer args in the call site") \ 5606c3fb27SDimitry Andric M(int64_t, {1}, callsite_cost, "Estimated cost of the call site") \ 5706c3fb27SDimitry Andric M(int64_t, {1}, cold_cc_penalty, "Penalty for a cold calling convention") \ 5806c3fb27SDimitry Andric M(int64_t, {1}, last_call_to_static_bonus, \ 5906c3fb27SDimitry Andric "Bonus for being the last call to static") \ 6006c3fb27SDimitry Andric M(int64_t, {1}, is_multiple_blocks, \ 6106c3fb27SDimitry Andric "Boolean; is the Callee multiple blocks") \ 6206c3fb27SDimitry Andric M(int64_t, {1}, nested_inlines, \ 6306c3fb27SDimitry Andric "Would the default inliner perfom nested inlining") \ 6406c3fb27SDimitry Andric M(int64_t, {1}, nested_inline_cost_estimate, \ 6506c3fb27SDimitry Andric "Estimate of the accumulated cost of nested inlines") \ 6606c3fb27SDimitry Andric M(int64_t, {1}, threshold, "Threshold for the heuristic inliner") 67fe6060f1SDimitry Andric 68fe6060f1SDimitry Andric // clang-format off 69fe6060f1SDimitry Andric enum class InlineCostFeatureIndex : size_t { 7006c3fb27SDimitry Andric #define POPULATE_INDICES(DTYPE, SHAPE, NAME, DOC) NAME, 71fe6060f1SDimitry Andric INLINE_COST_FEATURE_ITERATOR(POPULATE_INDICES) 72fe6060f1SDimitry Andric #undef POPULATE_INDICES 73fe6060f1SDimitry Andric 74fe6060f1SDimitry Andric NumberOfFeatures 75fe6060f1SDimitry Andric }; 76fe6060f1SDimitry Andric // clang-format on 77fe6060f1SDimitry Andric 78fe6060f1SDimitry Andric using InlineCostFeatures = 79fe6060f1SDimitry Andric std::array<int, 80fe6060f1SDimitry Andric static_cast<size_t>(InlineCostFeatureIndex::NumberOfFeatures)>; 81fe6060f1SDimitry Andric 82fe6060f1SDimitry Andric constexpr bool isHeuristicInlineCostFeature(InlineCostFeatureIndex Feature) { 8306c3fb27SDimitry Andric return Feature != InlineCostFeatureIndex::sroa_savings && 8406c3fb27SDimitry Andric Feature != InlineCostFeatureIndex::is_multiple_blocks && 8506c3fb27SDimitry Andric Feature != InlineCostFeatureIndex::dead_blocks && 8606c3fb27SDimitry Andric Feature != InlineCostFeatureIndex::simplified_instructions && 8706c3fb27SDimitry Andric Feature != InlineCostFeatureIndex::constant_args && 8806c3fb27SDimitry Andric Feature != InlineCostFeatureIndex::constant_offset_ptr_args && 8906c3fb27SDimitry Andric Feature != InlineCostFeatureIndex::nested_inlines && 9006c3fb27SDimitry Andric Feature != InlineCostFeatureIndex::nested_inline_cost_estimate && 9106c3fb27SDimitry Andric Feature != InlineCostFeatureIndex::threshold; 92fe6060f1SDimitry Andric } 93fe6060f1SDimitry Andric 945ffd83dbSDimitry Andric // List of features. Each feature is defined through a triple: 955ffd83dbSDimitry Andric // - the name of an enum member, which will be the feature index 965f757f3fSDimitry Andric // - a textual name, used for ML model binding (so it needs to match the 975f757f3fSDimitry Andric // names used by the ML model). 985ffd83dbSDimitry Andric // - a documentation description. Currently, that is not used anywhere 995ffd83dbSDimitry Andric // programmatically, and serves as workaround to inability of inserting comments 1005ffd83dbSDimitry Andric // in macros. 1015ffd83dbSDimitry Andric #define INLINE_FEATURE_ITERATOR(M) \ 10206c3fb27SDimitry Andric M(int64_t, {1}, callee_basic_block_count, \ 1035ffd83dbSDimitry Andric "number of basic blocks of the callee") \ 10406c3fb27SDimitry Andric M(int64_t, {1}, callsite_height, \ 1055ffd83dbSDimitry Andric "position of the call site in the original call graph - measured from " \ 1065ffd83dbSDimitry Andric "the farthest SCC") \ 10706c3fb27SDimitry Andric M(int64_t, {1}, node_count, \ 1085ffd83dbSDimitry Andric "total current number of defined functions in the module") \ 10906c3fb27SDimitry Andric M(int64_t, {1}, nr_ctant_params, \ 1105ffd83dbSDimitry Andric "number of parameters in the call site that are constants") \ 11106c3fb27SDimitry Andric M(int64_t, {1}, cost_estimate, "total cost estimate (threshold - free)") \ 11206c3fb27SDimitry Andric M(int64_t, {1}, edge_count, "total number of calls in the module") \ 11306c3fb27SDimitry Andric M(int64_t, {1}, caller_users, \ 1145ffd83dbSDimitry Andric "number of module-internal users of the caller, +1 if the caller is " \ 1155ffd83dbSDimitry Andric "exposed externally") \ 11606c3fb27SDimitry Andric M(int64_t, {1}, caller_conditionally_executed_blocks, \ 1175ffd83dbSDimitry Andric "number of blocks reached from a conditional instruction, in the caller") \ 11806c3fb27SDimitry Andric M(int64_t, {1}, caller_basic_block_count, \ 1195ffd83dbSDimitry Andric "number of basic blocks in the caller") \ 12006c3fb27SDimitry Andric M(int64_t, {1}, callee_conditionally_executed_blocks, \ 1215ffd83dbSDimitry Andric "number of blocks reached from a conditional instruction, in the callee") \ 12206c3fb27SDimitry Andric M(int64_t, {1}, callee_users, \ 123fe6060f1SDimitry Andric "number of module-internal users of the callee, +1 if the callee is " \ 124*0fca6ea1SDimitry Andric "exposed externally") \ 125*0fca6ea1SDimitry Andric M(int64_t, {1}, is_callee_avail_external, \ 126*0fca6ea1SDimitry Andric "Is callee an available-externally linkage type (i.e. could be DCEd if " \ 127*0fca6ea1SDimitry Andric "not " \ 128*0fca6ea1SDimitry Andric "fully inlined by ElimAvailExtern)") \ 129*0fca6ea1SDimitry Andric M(int64_t, {1}, is_caller_avail_external, \ 130*0fca6ea1SDimitry Andric "Is caller an available-externally linkage type (i.e. could be DCEd if " \ 131*0fca6ea1SDimitry Andric "not " \ 132*0fca6ea1SDimitry Andric "fully inlined by ElimAvailExtern)") 1335ffd83dbSDimitry Andric 134fe6060f1SDimitry Andric // clang-format off 1355ffd83dbSDimitry Andric enum class FeatureIndex : size_t { 13606c3fb27SDimitry Andric #define POPULATE_INDICES(DTYPE, SHAPE, NAME, COMMENT) NAME, 137fe6060f1SDimitry Andric // InlineCost features - these must come first 138fe6060f1SDimitry Andric INLINE_COST_FEATURE_ITERATOR(POPULATE_INDICES) 139fe6060f1SDimitry Andric 140fe6060f1SDimitry Andric // Non-cost features 1415ffd83dbSDimitry Andric INLINE_FEATURE_ITERATOR(POPULATE_INDICES) 1425ffd83dbSDimitry Andric #undef POPULATE_INDICES 143fe6060f1SDimitry Andric 1445ffd83dbSDimitry Andric NumberOfFeatures 1455ffd83dbSDimitry Andric }; 146fe6060f1SDimitry Andric // clang-format on 147fe6060f1SDimitry Andric 148fe6060f1SDimitry Andric constexpr FeatureIndex 149fe6060f1SDimitry Andric inlineCostFeatureToMlFeature(InlineCostFeatureIndex Feature) { 150fe6060f1SDimitry Andric return static_cast<FeatureIndex>(static_cast<size_t>(Feature)); 151fe6060f1SDimitry Andric } 1525ffd83dbSDimitry Andric 1535ffd83dbSDimitry Andric constexpr size_t NumberOfFeatures = 1545ffd83dbSDimitry Andric static_cast<size_t>(FeatureIndex::NumberOfFeatures); 1555ffd83dbSDimitry Andric 15606c3fb27SDimitry Andric extern const std::vector<TensorSpec> FeatureMap; 1575ffd83dbSDimitry Andric 1585ffd83dbSDimitry Andric extern const char *const DecisionName; 15906c3fb27SDimitry Andric extern const TensorSpec InlineDecisionSpec; 1605ffd83dbSDimitry Andric extern const char *const DefaultDecisionName; 16106c3fb27SDimitry Andric extern const TensorSpec DefaultDecisionSpec; 1625ffd83dbSDimitry Andric extern const char *const RewardName; 1635ffd83dbSDimitry Andric 1645ffd83dbSDimitry Andric using InlineFeatures = std::vector<int64_t>; 1655ffd83dbSDimitry Andric 1665ffd83dbSDimitry Andric } // namespace llvm 1675ffd83dbSDimitry Andric #endif // LLVM_ANALYSIS_INLINEMODELFEATUREMAPS_H 168