1 //===- InlineModelFeatureMaps.h - common model runner defs ------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 10 #ifndef LLVM_ANALYSIS_INLINEMODELFEATUREMAPS_H 11 #define LLVM_ANALYSIS_INLINEMODELFEATUREMAPS_H 12 13 #include "llvm/Analysis/TensorSpec.h" 14 15 #include <array> 16 #include <string> 17 #include <vector> 18 19 namespace llvm { 20 21 // List of cost features. A "cost" feature is a summand of the heuristic-based 22 // inline cost, and we define them separately to preserve the original heuristic 23 // behavior. 24 #define INLINE_COST_FEATURE_ITERATOR(M) \ 25 M(int64_t, {1}, sroa_savings, \ 26 "Savings from SROA (scalar replacement of aggregates)") \ 27 M(int64_t, {1}, sroa_losses, \ 28 "Losses from SROA (scalar replacement of aggregates)") \ 29 M(int64_t, {1}, load_elimination, "Cost of load elimination in the call") \ 30 M(int64_t, {1}, call_penalty, \ 31 "Accumulation of penalty applied to call sites when inlining") \ 32 M(int64_t, {1}, call_argument_setup, \ 33 "Accumulation of call argument setup costs") \ 34 M(int64_t, {1}, load_relative_intrinsic, \ 35 "Accumulation of costs of loading relative intrinsics") \ 36 M(int64_t, {1}, lowered_call_arg_setup, \ 37 "Accumulation of cost of lowered call argument setups") \ 38 M(int64_t, {1}, indirect_call_penalty, \ 39 "Accumulation of costs for indirect calls") \ 40 M(int64_t, {1}, jump_table_penalty, "Accumulation of costs for jump tables") \ 41 M(int64_t, {1}, case_cluster_penalty, \ 42 "Accumulation of costs for case clusters") \ 43 M(int64_t, {1}, switch_penalty, \ 44 "Accumulation of costs for switch statements") \ 45 M(int64_t, {1}, unsimplified_common_instructions, \ 46 "Costs from unsimplified common instructions") \ 47 M(int64_t, {1}, num_loops, "Number of loops in the caller") \ 48 M(int64_t, {1}, dead_blocks, "Number of dead blocks in the caller") \ 49 M(int64_t, {1}, simplified_instructions, \ 50 "Number of simplified instructions") \ 51 M(int64_t, {1}, constant_args, \ 52 "Number of constant arguments in the call site") \ 53 M(int64_t, {1}, constant_offset_ptr_args, \ 54 "Number of constant offset pointer args in the call site") \ 55 M(int64_t, {1}, callsite_cost, "Estimated cost of the call site") \ 56 M(int64_t, {1}, cold_cc_penalty, "Penalty for a cold calling convention") \ 57 M(int64_t, {1}, last_call_to_static_bonus, \ 58 "Bonus for being the last call to static") \ 59 M(int64_t, {1}, is_multiple_blocks, \ 60 "Boolean; is the Callee multiple blocks") \ 61 M(int64_t, {1}, nested_inlines, \ 62 "Would the default inliner perfom nested inlining") \ 63 M(int64_t, {1}, nested_inline_cost_estimate, \ 64 "Estimate of the accumulated cost of nested inlines") \ 65 M(int64_t, {1}, threshold, "Threshold for the heuristic inliner") 66 67 // clang-format off 68 enum class InlineCostFeatureIndex : size_t { 69 #define POPULATE_INDICES(DTYPE, SHAPE, NAME, DOC) NAME, 70 INLINE_COST_FEATURE_ITERATOR(POPULATE_INDICES) 71 #undef POPULATE_INDICES 72 73 NumberOfFeatures 74 }; 75 // clang-format on 76 77 using InlineCostFeatures = 78 std::array<int, 79 static_cast<size_t>(InlineCostFeatureIndex::NumberOfFeatures)>; 80 81 constexpr bool isHeuristicInlineCostFeature(InlineCostFeatureIndex Feature) { 82 return Feature != InlineCostFeatureIndex::sroa_savings && 83 Feature != InlineCostFeatureIndex::is_multiple_blocks && 84 Feature != InlineCostFeatureIndex::dead_blocks && 85 Feature != InlineCostFeatureIndex::simplified_instructions && 86 Feature != InlineCostFeatureIndex::constant_args && 87 Feature != InlineCostFeatureIndex::constant_offset_ptr_args && 88 Feature != InlineCostFeatureIndex::nested_inlines && 89 Feature != InlineCostFeatureIndex::nested_inline_cost_estimate && 90 Feature != InlineCostFeatureIndex::threshold; 91 } 92 93 // List of features. Each feature is defined through a triple: 94 // - the name of an enum member, which will be the feature index 95 // - a textual name, used for Tensorflow model binding (so it needs to match the 96 // names used by the Tensorflow model) 97 // - a documentation description. Currently, that is not used anywhere 98 // programmatically, and serves as workaround to inability of inserting comments 99 // in macros. 100 #define INLINE_FEATURE_ITERATOR(M) \ 101 M(int64_t, {1}, callee_basic_block_count, \ 102 "number of basic blocks of the callee") \ 103 M(int64_t, {1}, callsite_height, \ 104 "position of the call site in the original call graph - measured from " \ 105 "the farthest SCC") \ 106 M(int64_t, {1}, node_count, \ 107 "total current number of defined functions in the module") \ 108 M(int64_t, {1}, nr_ctant_params, \ 109 "number of parameters in the call site that are constants") \ 110 M(int64_t, {1}, cost_estimate, "total cost estimate (threshold - free)") \ 111 M(int64_t, {1}, edge_count, "total number of calls in the module") \ 112 M(int64_t, {1}, caller_users, \ 113 "number of module-internal users of the caller, +1 if the caller is " \ 114 "exposed externally") \ 115 M(int64_t, {1}, caller_conditionally_executed_blocks, \ 116 "number of blocks reached from a conditional instruction, in the caller") \ 117 M(int64_t, {1}, caller_basic_block_count, \ 118 "number of basic blocks in the caller") \ 119 M(int64_t, {1}, callee_conditionally_executed_blocks, \ 120 "number of blocks reached from a conditional instruction, in the callee") \ 121 M(int64_t, {1}, callee_users, \ 122 "number of module-internal users of the callee, +1 if the callee is " \ 123 "exposed externally") 124 125 // clang-format off 126 enum class FeatureIndex : size_t { 127 #define POPULATE_INDICES(DTYPE, SHAPE, NAME, COMMENT) NAME, 128 // InlineCost features - these must come first 129 INLINE_COST_FEATURE_ITERATOR(POPULATE_INDICES) 130 131 // Non-cost features 132 INLINE_FEATURE_ITERATOR(POPULATE_INDICES) 133 #undef POPULATE_INDICES 134 135 NumberOfFeatures 136 }; 137 // clang-format on 138 139 constexpr FeatureIndex 140 inlineCostFeatureToMlFeature(InlineCostFeatureIndex Feature) { 141 return static_cast<FeatureIndex>(static_cast<size_t>(Feature)); 142 } 143 144 constexpr size_t NumberOfFeatures = 145 static_cast<size_t>(FeatureIndex::NumberOfFeatures); 146 147 extern const std::vector<TensorSpec> FeatureMap; 148 149 extern const char *const DecisionName; 150 extern const TensorSpec InlineDecisionSpec; 151 extern const char *const DefaultDecisionName; 152 extern const TensorSpec DefaultDecisionSpec; 153 extern const char *const RewardName; 154 155 using InlineFeatures = std::vector<int64_t>; 156 157 } // namespace llvm 158 #endif // LLVM_ANALYSIS_INLINEMODELFEATUREMAPS_H 159