mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-24 22:32:47 +00:00
e0f0e0be1c
- This matches llvm-ld. It took a bit of archeology to figure out what the right thing to do was (whether this was intentionally added or intentionally removed). My final conclusion is that Chris added this intentionally here: http://llvm.org/viewvc/llvm-project?view=rev&revision=16913 but the changes weren't propogated to llvm-ld until here: http://llvm.org/viewvc/llvm-project?view=rev&revision=34058 which was after lto.cpp had been cloned off (of llvm-ld), here: http://llvm.org/viewvc/llvm-project?view=rev&revision=29494 From the commit message, it looks like the motivation for running global opt again is because we ran it prior to inlining. Based on that I updated the comment and also only run the pass if we actually ran the inliner. Chris, please review. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72811 91177308-0d34-0410-b5e6-96231b3b80d8
245 lines
11 KiB
C++
245 lines
11 KiB
C++
//===-- llvm/Support/StandardPasses.h - Standard pass lists -----*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines utility functions for creating a "standard" set of
|
|
// optimization passes, so that compilers and tools which use optimization
|
|
// passes use the same set of standard passes.
|
|
//
|
|
// These are implemented as inline functions so that we do not have to worry
|
|
// about link issues.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_SUPPORT_STANDARDPASSES_H
|
|
#define LLVM_SUPPORT_STANDARDPASSES_H
|
|
|
|
#include "llvm/PassManager.h"
|
|
#include "llvm/Analysis/Passes.h"
|
|
#include "llvm/Analysis/Verifier.h"
|
|
#include "llvm/Transforms/Scalar.h"
|
|
#include "llvm/Transforms/IPO.h"
|
|
|
|
namespace llvm {
|
|
/// createStandardFunctionPasses - Add the standard list of function passes to
|
|
/// the provided pass manager.
|
|
///
|
|
/// \arg OptimizationLevel - The optimization level, corresponding to -O0,
|
|
/// -O1, etc.
|
|
static inline void createStandardFunctionPasses(FunctionPassManager *PM,
|
|
unsigned OptimizationLevel);
|
|
|
|
/// createStandardModulePasses - Add the standard list of module passes to the
|
|
/// provided pass manager.
|
|
///
|
|
/// \arg OptimizationLevel - The optimization level, corresponding to -O0,
|
|
/// -O1, etc.
|
|
/// \arg OptimizeSize - Whether the transformations should optimize for size.
|
|
/// \arg UnitAtATime - Allow passes which may make global module changes.
|
|
/// \arg UnrollLoops - Allow loop unrolling.
|
|
/// \arg SimplifyLibCalls - Allow library calls to be simplified.
|
|
/// \arg HaveExceptions - Whether the module may have code using exceptions.
|
|
/// \arg InliningPass - The inlining pass to use, if any, or null. This will
|
|
/// always be added, even at -O0.a
|
|
static inline void createStandardModulePasses(PassManager *PM,
|
|
unsigned OptimizationLevel,
|
|
bool OptimizeSize,
|
|
bool UnitAtATime,
|
|
bool UnrollLoops,
|
|
bool SimplifyLibCalls,
|
|
bool HaveExceptions,
|
|
Pass *InliningPass);
|
|
|
|
/// createStandardLTOPasses - Add the standard list of module passes suitable
|
|
/// for link time optimization.
|
|
///
|
|
/// Internalize - Run the internalize pass.
|
|
/// RunInliner - Use a function inlining pass.
|
|
/// VerifyEach - Run the verifier after each pass.
|
|
static inline void createStandardLTOPasses(PassManager *PM,
|
|
bool Internalize,
|
|
bool RunInliner,
|
|
bool VerifyEach);
|
|
|
|
// Implementations
|
|
|
|
static inline void createStandardFunctionPasses(FunctionPassManager *PM,
|
|
unsigned OptimizationLevel) {
|
|
if (OptimizationLevel > 0) {
|
|
PM->add(createCFGSimplificationPass());
|
|
if (OptimizationLevel == 1)
|
|
PM->add(createPromoteMemoryToRegisterPass());
|
|
else
|
|
PM->add(createScalarReplAggregatesPass());
|
|
PM->add(createInstructionCombiningPass());
|
|
}
|
|
}
|
|
|
|
static inline void createStandardModulePasses(PassManager *PM,
|
|
unsigned OptimizationLevel,
|
|
bool OptimizeSize,
|
|
bool UnitAtATime,
|
|
bool UnrollLoops,
|
|
bool SimplifyLibCalls,
|
|
bool HaveExceptions,
|
|
Pass *InliningPass) {
|
|
if (OptimizationLevel == 0) {
|
|
if (InliningPass)
|
|
PM->add(InliningPass);
|
|
} else {
|
|
if (UnitAtATime)
|
|
PM->add(createRaiseAllocationsPass()); // call %malloc -> malloc inst
|
|
PM->add(createCFGSimplificationPass()); // Clean up disgusting code
|
|
// Kill useless allocas
|
|
PM->add(createPromoteMemoryToRegisterPass());
|
|
if (UnitAtATime) {
|
|
PM->add(createGlobalOptimizerPass()); // Optimize out global vars
|
|
PM->add(createGlobalDCEPass()); // Remove unused fns and globs
|
|
// IP Constant Propagation
|
|
PM->add(createIPConstantPropagationPass());
|
|
PM->add(createDeadArgEliminationPass()); // Dead argument elimination
|
|
}
|
|
PM->add(createInstructionCombiningPass()); // Clean up after IPCP & DAE
|
|
PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE
|
|
if (UnitAtATime) {
|
|
if (HaveExceptions)
|
|
PM->add(createPruneEHPass()); // Remove dead EH info
|
|
PM->add(createFunctionAttrsPass()); // Set readonly/readnone attrs
|
|
}
|
|
if (InliningPass)
|
|
PM->add(InliningPass);
|
|
if (OptimizationLevel > 2)
|
|
PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args
|
|
if (SimplifyLibCalls)
|
|
PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations
|
|
PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl.
|
|
PM->add(createJumpThreadingPass()); // Thread jumps.
|
|
PM->add(createCFGSimplificationPass()); // Merge & remove BBs
|
|
PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas
|
|
PM->add(createInstructionCombiningPass()); // Combine silly seq's
|
|
PM->add(createCondPropagationPass()); // Propagate conditionals
|
|
PM->add(createTailCallEliminationPass()); // Eliminate tail calls
|
|
PM->add(createCFGSimplificationPass()); // Merge & remove BBs
|
|
PM->add(createReassociatePass()); // Reassociate expressions
|
|
PM->add(createLoopRotatePass()); // Rotate Loop
|
|
PM->add(createLICMPass()); // Hoist loop invariants
|
|
PM->add(createLoopUnswitchPass(OptimizeSize));
|
|
PM->add(createLoopIndexSplitPass()); // Split loop index
|
|
PM->add(createInstructionCombiningPass());
|
|
PM->add(createIndVarSimplifyPass()); // Canonicalize indvars
|
|
PM->add(createLoopDeletionPass()); // Delete dead loops
|
|
if (UnrollLoops)
|
|
PM->add(createLoopUnrollPass()); // Unroll small loops
|
|
PM->add(createInstructionCombiningPass()); // Clean up after the unroller
|
|
PM->add(createGVNPass()); // Remove redundancies
|
|
PM->add(createMemCpyOptPass()); // Remove memcpy / form memset
|
|
PM->add(createSCCPPass()); // Constant prop with SCCP
|
|
|
|
// Run instcombine after redundancy elimination to exploit opportunities
|
|
// opened up by them.
|
|
PM->add(createInstructionCombiningPass());
|
|
PM->add(createCondPropagationPass()); // Propagate conditionals
|
|
PM->add(createDeadStoreEliminationPass()); // Delete dead stores
|
|
PM->add(createAggressiveDCEPass()); // Delete dead instructions
|
|
PM->add(createCFGSimplificationPass()); // Merge & remove BBs
|
|
|
|
if (UnitAtATime) {
|
|
PM->add(createStripDeadPrototypesPass()); // Get rid of dead prototypes
|
|
PM->add(createDeadTypeEliminationPass()); // Eliminate dead types
|
|
}
|
|
|
|
if (OptimizationLevel > 1 && UnitAtATime)
|
|
PM->add(createConstantMergePass()); // Merge dup global constants
|
|
}
|
|
}
|
|
|
|
static inline void addOnePass(PassManager *PM, Pass *P, bool AndVerify) {
|
|
PM->add(P);
|
|
|
|
if (AndVerify)
|
|
PM->add(createVerifierPass());
|
|
}
|
|
|
|
static inline void createStandardLTOPasses(PassManager *PM,
|
|
bool Internalize,
|
|
bool RunInliner,
|
|
bool VerifyEach) {
|
|
// Now that composite has been compiled, scan through the module, looking
|
|
// for a main function. If main is defined, mark all other functions
|
|
// internal.
|
|
if (Internalize)
|
|
addOnePass(PM, createInternalizePass(true), VerifyEach);
|
|
|
|
// Propagate constants at call sites into the functions they call. This
|
|
// opens opportunities for globalopt (and inlining) by substituting function
|
|
// pointers passed as arguments to direct uses of functions.
|
|
addOnePass(PM, createIPSCCPPass(), VerifyEach);
|
|
|
|
// Now that we internalized some globals, see if we can hack on them!
|
|
addOnePass(PM, createGlobalOptimizerPass(), VerifyEach);
|
|
|
|
// Linking modules together can lead to duplicated global constants, only
|
|
// keep one copy of each constant...
|
|
addOnePass(PM, createConstantMergePass(), VerifyEach);
|
|
|
|
// Remove unused arguments from functions...
|
|
addOnePass(PM, createDeadArgEliminationPass(), VerifyEach);
|
|
|
|
// Reduce the code after globalopt and ipsccp. Both can open up significant
|
|
// simplification opportunities, and both can propagate functions through
|
|
// function pointers. When this happens, we often have to resolve varargs
|
|
// calls, etc, so let instcombine do this.
|
|
addOnePass(PM, createInstructionCombiningPass(), VerifyEach);
|
|
|
|
// Inline small functions
|
|
if (RunInliner)
|
|
addOnePass(PM, createFunctionInliningPass(), VerifyEach);
|
|
|
|
addOnePass(PM, createPruneEHPass(), VerifyEach); // Remove dead EH info.
|
|
// Optimize globals again if we ran the inliner.
|
|
if (RunInliner)
|
|
addOnePass(PM, createGlobalOptimizerPass(), VerifyEach);
|
|
addOnePass(PM, createGlobalDCEPass(), VerifyEach); // Remove dead functions.
|
|
|
|
// If we didn't decide to inline a function, check to see if we can
|
|
// transform it to pass arguments by value instead of by reference.
|
|
addOnePass(PM, createArgumentPromotionPass(), VerifyEach);
|
|
|
|
// The IPO passes may leave cruft around. Clean up after them.
|
|
addOnePass(PM, createInstructionCombiningPass(), VerifyEach);
|
|
addOnePass(PM, createJumpThreadingPass(), VerifyEach);
|
|
// Break up allocas
|
|
addOnePass(PM, createScalarReplAggregatesPass(), VerifyEach);
|
|
|
|
// Run a few AA driven optimizations here and now, to cleanup the code.
|
|
addOnePass(PM, createFunctionAttrsPass(), VerifyEach); // Add nocapture.
|
|
addOnePass(PM, createGlobalsModRefPass(), VerifyEach); // IP alias analysis.
|
|
|
|
addOnePass(PM, createLICMPass(), VerifyEach); // Hoist loop invariants.
|
|
addOnePass(PM, createGVNPass(), VerifyEach); // Remove redundancies.
|
|
addOnePass(PM, createMemCpyOptPass(), VerifyEach); // Remove dead memcpys.
|
|
// Nuke dead stores.
|
|
addOnePass(PM, createDeadStoreEliminationPass(), VerifyEach);
|
|
|
|
// Cleanup and simplify the code after the scalar optimizations.
|
|
addOnePass(PM, createInstructionCombiningPass(), VerifyEach);
|
|
|
|
addOnePass(PM, createJumpThreadingPass(), VerifyEach);
|
|
// Cleanup jump threading.
|
|
addOnePass(PM, createPromoteMemoryToRegisterPass(), VerifyEach);
|
|
|
|
// Delete basic blocks, which optimization passes may have killed...
|
|
addOnePass(PM, createCFGSimplificationPass(), VerifyEach);
|
|
|
|
// Now that we have optimized the program, discard unreachable functions.
|
|
addOnePass(PM, createGlobalDCEPass(), VerifyEach);
|
|
}
|
|
}
|
|
|
|
#endif
|