Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Standalone View
llvm/include/llvm/Analysis/InlineOrder.h
Show All 26 Lines | public: | ||||
virtual T pop() = 0; | virtual T pop() = 0; | ||||
virtual void erase_if(function_ref<bool(T)> Pred) = 0; | virtual void erase_if(function_ref<bool(T)> Pred) = 0; | ||||
bool empty() { return !size(); } | bool empty() { return !size(); } | ||||
}; | }; | ||||
std::unique_ptr<InlineOrder<std::pair<CallBase *, int>>> | std::unique_ptr<InlineOrder<std::pair<CallBase *, int>>> | ||||
getInlineOrder(FunctionAnalysisManager &FAM, const InlineParams &Params); | getInlineOrder(FunctionAnalysisManager &FAM, const InlineParams &Params, | ||||
ModuleAnalysisManager &MAM, Module &M); | |||||
/// Used for dynamically registering InlineOrder as plugins | |||||
/// | |||||
/// An inline order plugin adds a new inline order at runtime by registering | |||||
/// an instance of PluginInlineOrderAnalysis in the current | |||||
/// ModuleAnalysisManager. For example, the following code dynamically registers | |||||
/// the default inline order: | |||||
kazu: Sorry, I am slow to understand this. Is the following correct understanding? | |||||
An instance of PluginInlineOrderAnalysis only exists if it has been registered, in a normal compilation it won't exist. If it's registered then indeed it's Factory will be used to create a custom order IBricchi: An instance of PluginInlineOrderAnalysis only exists if it has been registered, in a normal… | |||||
/// | |||||
/// namespace { | |||||
/// | |||||
/// std::unique_ptr<InlineOrder<std::pair<CallBase *, int>>> | |||||
/// DefaultInlineOrderFactory(FunctionAnalysisManager &FAM, | |||||
/// const InlineParams &Params, | |||||
/// ModuleAnalysisManager &MAM, Module &M) { | |||||
/// llvm::PluginInlineOrderAnalysis::HasBeenRegistered = false; | |||||
/// auto DefaultInlineOrder = | |||||
Could we make this variable private and provide accessors like so? static bool isRegistered() { return HasBeenRegistered; } static void unregister() { HasBeenRegistered = false; } I am suggesting this because I don't want anyone to set HasBeenRegistered to true except in the constructor here. kazu: Could we make this variable private and provide accessors like so?
```
static bool… | |||||
/// std::unique_ptr<InlineOrder<std::pair<CallBase *, int>>>( | |||||
/// getInlineOrder(FAM, Params, MAM, M)); | |||||
/// llvm::PluginInlineOrderAnalysis::HasBeenRegistered = true; | |||||
/// return DefaultInlineOrder; | |||||
/// } | |||||
/// | |||||
/// struct DefaultDynamicInlineOrder : PassInfoMixin<DefaultDynamicInlineOrder> | |||||
/// { | |||||
/// PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM) { | |||||
/// PluginInlineOrderAnalysis DA(DefaultInlineOrderFactory); | |||||
/// MAM.registerPass([&] { return DA; }); | |||||
/// return PreservedAnalyses::all(); | |||||
/// } | |||||
/// }; | |||||
/// | |||||
/// } // namespace | |||||
/// | |||||
/// extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo | |||||
/// llvmGetPassPluginInfo() { | |||||
/// return {LLVM_PLUGIN_API_VERSION, "DefaultDynamicInlineOrder", | |||||
/// LLVM_VERSION_STRING, | |||||
/// [](PassBuilder &PB) { | |||||
/// PB.registerPipelineStartEPCallback( | |||||
/// [](ModulePassManager &MPM, OptimizationLevel Level) { | |||||
/// MPM.addPass(DefaultDynamicInlineOrder()); | |||||
/// }); | |||||
/// }}; | |||||
/// } | |||||
Not Done ReplyInline ActionsCould we document the plugin as inline comments in llvm/unittests/Analysis/InlineOrderPlugin/InlineOrderPlugin.cpp or something? I am afraid that the big code block comments might diverge from what the actual code should look like. If you are OK with this idea, you might want to put a pointer to the example file here. kazu: Could we document the plugin as inline comments in… | |||||
/// | |||||
/// A plugin must implement an InlineOrderFactory and register it with a | |||||
/// PluginInlineOrderAnalysis to the provided ModuleanAlysisManager. | |||||
ModuleAnalysisManager? kazu: `ModuleAnalysisManager`? | |||||
/// | |||||
/// If such a plugin has been registered | |||||
/// llvm::getInlineOrder will return the dynamically loaded inliner order. | |||||
/// | |||||
class PluginInlineOrderAnalysis | |||||
: public AnalysisInfoMixin<PluginInlineOrderAnalysis> { | |||||
public: | |||||
static AnalysisKey Key; | |||||
static bool HasBeenRegistered; | |||||
typedef std::unique_ptr<InlineOrder<std::pair<CallBase *, int>>> ( | |||||
*InlineOrderFactory)(FunctionAnalysisManager &FAM, | |||||
const InlineParams &Params, | |||||
ModuleAnalysisManager &MAM, Module &M); | |||||
PluginInlineOrderAnalysis(InlineOrderFactory Factory) : Factory(Factory) { | |||||
HasBeenRegistered = true; | |||||
assert(Factory != nullptr && | |||||
"The plugin inline order factory should not be a null pointer."); | |||||
} | |||||
// This is needed for unit tests where plugins may be deregistered. | |||||
// Otherwise the static varaible will stay true and if getInlineOrder | |||||
// is called it will try to load a non-registered advisor and crash. | |||||
~PluginInlineOrderAnalysis() { HasBeenRegistered = false; } | |||||
struct Result { | |||||
InlineOrderFactory Factory; | |||||
}; | |||||
Result run(Module &, ModuleAnalysisManager &) { return {Factory}; } | |||||
Result getResult() { return {Factory}; } | |||||
private: | |||||
InlineOrderFactory Factory; | |||||
}; | |||||
} // namespace llvm | } // namespace llvm | ||||
#endif // LLVM_ANALYSIS_INLINEORDER_H | #endif // LLVM_ANALYSIS_INLINEORDER_H |
Sorry, I am slow to understand this. Is the following correct understanding?
PluginInlineOrderAnalysis is always there, regardless of whether you have a plugin. If you actually have a plugin, we can use Factory in PluginInlineOrderAnalysis to construct a custom inline order.
Now, why are we using an analysis here? Is that because it's a good hook to use?