mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-15 18:49:51 +00:00
![Chandler Carruth](/assets/img/avatar_default.png)
minimal and boring form than the old pass manager's version. This pass does the very minimal amount of work necessary to inline functions declared as always-inline. It doesn't support a wide array of things that the legacy pass manager did support, but is alse ... about 20 lines of code. So it has that going for it. Notably things this doesn't support: - Array alloca merging - To support the above, bottom-up inlining with careful history tracking and call graph updates - DCE of the functions that become dead after this inlining. - Inlining through call instructions with the always_inline attribute. Instead, it focuses on inlining functions with that attribute. The first I've omitted because I'm hoping to just turn it off for the primary pass manager. If that doesn't pan out, I can add it here but it will be reasonably expensive to do so. The second should really be handled by running global-dce after the inliner. I don't want to re-implement the non-trivial logic necessary to do comdat-correct DCE of functions. This means the -O0 pipeline will have to be at least 'always-inline,global-dce', but that seems reasonable to me. If others are seriously worried about this I'd like to hear about it and understand why. Again, this is all solveable by factoring that logic into a utility and calling it here, but I'd like to wait to do that until there is a clear reason why the existing pass-based factoring won't work. The final point is a serious one. I can fairly easily add support for this, but it seems both costly and a confusing construct for the use case of the always inliner running at -O0. This attribute can of course still impact the normal inliner easily (although I find that a questionable re-use of the same attribute). I've started a discussion to sort out what semantics we want here and based on that can figure out if it makes sense ta have this complexity at O0 or not. One other advantage of this design is that it should be quite a bit faster due to checking for whether the function is a viable candidate for inlining exactly once per function instead of doing it for each call site. Anyways, hopefully a reasonable starting point for this pass. Differential Revision: https://reviews.llvm.org/D23299 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278896 91177308-0d34-0410-b5e6-96231b3b80d8
123 lines
4.1 KiB
C++
123 lines
4.1 KiB
C++
//===-- IPO.cpp -----------------------------------------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the common infrastructure (including C bindings) for
|
|
// libLLVMIPO.a, which implements several transformations over the LLVM
|
|
// intermediate representation.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm-c/Initialization.h"
|
|
#include "llvm-c/Transforms/IPO.h"
|
|
#include "llvm/InitializePasses.h"
|
|
#include "llvm/IR/LegacyPassManager.h"
|
|
#include "llvm/Transforms/IPO.h"
|
|
#include "llvm/Transforms/IPO/AlwaysInliner.h"
|
|
#include "llvm/Transforms/IPO/FunctionAttrs.h"
|
|
|
|
using namespace llvm;
|
|
|
|
void llvm::initializeIPO(PassRegistry &Registry) {
|
|
initializeArgPromotionPass(Registry);
|
|
initializeConstantMergeLegacyPassPass(Registry);
|
|
initializeCrossDSOCFIPass(Registry);
|
|
initializeDAEPass(Registry);
|
|
initializeDAHPass(Registry);
|
|
initializeForceFunctionAttrsLegacyPassPass(Registry);
|
|
initializeGlobalDCELegacyPassPass(Registry);
|
|
initializeGlobalOptLegacyPassPass(Registry);
|
|
initializeIPCPPass(Registry);
|
|
initializeAlwaysInlinerLegacyPassPass(Registry);
|
|
initializeSimpleInlinerPass(Registry);
|
|
initializeInferFunctionAttrsLegacyPassPass(Registry);
|
|
initializeInternalizeLegacyPassPass(Registry);
|
|
initializeLoopExtractorPass(Registry);
|
|
initializeBlockExtractorPassPass(Registry);
|
|
initializeSingleLoopExtractorPass(Registry);
|
|
initializeLowerTypeTestsPass(Registry);
|
|
initializeMergeFunctionsPass(Registry);
|
|
initializePartialInlinerLegacyPassPass(Registry);
|
|
initializePostOrderFunctionAttrsLegacyPassPass(Registry);
|
|
initializeReversePostOrderFunctionAttrsLegacyPassPass(Registry);
|
|
initializePruneEHPass(Registry);
|
|
initializeStripDeadPrototypesLegacyPassPass(Registry);
|
|
initializeStripSymbolsPass(Registry);
|
|
initializeStripDebugDeclarePass(Registry);
|
|
initializeStripDeadDebugInfoPass(Registry);
|
|
initializeStripNonDebugSymbolsPass(Registry);
|
|
initializeBarrierNoopPass(Registry);
|
|
initializeEliminateAvailableExternallyLegacyPassPass(Registry);
|
|
initializeSampleProfileLoaderLegacyPassPass(Registry);
|
|
initializeFunctionImportLegacyPassPass(Registry);
|
|
initializeWholeProgramDevirtPass(Registry);
|
|
}
|
|
|
|
void LLVMInitializeIPO(LLVMPassRegistryRef R) {
|
|
initializeIPO(*unwrap(R));
|
|
}
|
|
|
|
void LLVMAddArgumentPromotionPass(LLVMPassManagerRef PM) {
|
|
unwrap(PM)->add(createArgumentPromotionPass());
|
|
}
|
|
|
|
void LLVMAddConstantMergePass(LLVMPassManagerRef PM) {
|
|
unwrap(PM)->add(createConstantMergePass());
|
|
}
|
|
|
|
void LLVMAddDeadArgEliminationPass(LLVMPassManagerRef PM) {
|
|
unwrap(PM)->add(createDeadArgEliminationPass());
|
|
}
|
|
|
|
void LLVMAddFunctionAttrsPass(LLVMPassManagerRef PM) {
|
|
unwrap(PM)->add(createPostOrderFunctionAttrsLegacyPass());
|
|
}
|
|
|
|
void LLVMAddFunctionInliningPass(LLVMPassManagerRef PM) {
|
|
unwrap(PM)->add(createFunctionInliningPass());
|
|
}
|
|
|
|
void LLVMAddAlwaysInlinerPass(LLVMPassManagerRef PM) {
|
|
unwrap(PM)->add(llvm::createAlwaysInlinerLegacyPass());
|
|
}
|
|
|
|
void LLVMAddGlobalDCEPass(LLVMPassManagerRef PM) {
|
|
unwrap(PM)->add(createGlobalDCEPass());
|
|
}
|
|
|
|
void LLVMAddGlobalOptimizerPass(LLVMPassManagerRef PM) {
|
|
unwrap(PM)->add(createGlobalOptimizerPass());
|
|
}
|
|
|
|
void LLVMAddIPConstantPropagationPass(LLVMPassManagerRef PM) {
|
|
unwrap(PM)->add(createIPConstantPropagationPass());
|
|
}
|
|
|
|
void LLVMAddPruneEHPass(LLVMPassManagerRef PM) {
|
|
unwrap(PM)->add(createPruneEHPass());
|
|
}
|
|
|
|
void LLVMAddIPSCCPPass(LLVMPassManagerRef PM) {
|
|
unwrap(PM)->add(createIPSCCPPass());
|
|
}
|
|
|
|
void LLVMAddInternalizePass(LLVMPassManagerRef PM, unsigned AllButMain) {
|
|
auto PreserveMain = [=](const GlobalValue &GV) {
|
|
return AllButMain && GV.getName() == "main";
|
|
};
|
|
unwrap(PM)->add(createInternalizePass(PreserveMain));
|
|
}
|
|
|
|
void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM) {
|
|
unwrap(PM)->add(createStripDeadPrototypesPass());
|
|
}
|
|
|
|
void LLVMAddStripSymbolsPass(LLVMPassManagerRef PM) {
|
|
unwrap(PM)->add(createStripSymbolsPass());
|
|
}
|