LLVM 20.0.0git
|
This file implements the loop fusion pass. More...
#include "llvm/Transforms/Scalar/LoopFuse.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/DependenceAnalysis.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/CodeMoverUtils.h"
#include "llvm/Transforms/Utils/LoopPeel.h"
#include "llvm/Transforms/Utils/LoopSimplify.h"
Go to the source code of this file.
Macros | |
#define | DEBUG_TYPE "loop-fusion" |
Enumerations | |
enum | FusionDependenceAnalysisChoice { FUSION_DEPENDENCE_ANALYSIS_SCEV , FUSION_DEPENDENCE_ANALYSIS_DA , FUSION_DEPENDENCE_ANALYSIS_ALL } |
Functions | |
STATISTIC (FuseCounter, "Loops fused") | |
STATISTIC (NumFusionCandidates, "Number of candidates for loop fusion") | |
STATISTIC (InvalidPreheader, "Loop has invalid preheader") | |
STATISTIC (InvalidHeader, "Loop has invalid header") | |
STATISTIC (InvalidExitingBlock, "Loop has invalid exiting blocks") | |
STATISTIC (InvalidExitBlock, "Loop has invalid exit block") | |
STATISTIC (InvalidLatch, "Loop has invalid latch") | |
STATISTIC (InvalidLoop, "Loop is invalid") | |
STATISTIC (AddressTakenBB, "Basic block has address taken") | |
STATISTIC (MayThrowException, "Loop may throw an exception") | |
STATISTIC (ContainsVolatileAccess, "Loop contains a volatile access") | |
STATISTIC (NotSimplifiedForm, "Loop is not in simplified form") | |
STATISTIC (InvalidDependencies, "Dependencies prevent fusion") | |
STATISTIC (UnknownTripCount, "Loop has unknown trip count") | |
STATISTIC (UncomputableTripCount, "SCEV cannot compute trip count of loop") | |
STATISTIC (NonEqualTripCount, "Loop trip counts are not the same") | |
STATISTIC (NonAdjacent, "Loops are not adjacent") | |
STATISTIC (NonEmptyPreheader, "Loop has a non-empty preheader with instructions that cannot be moved") | |
STATISTIC (FusionNotBeneficial, "Fusion is not beneficial") | |
STATISTIC (NonIdenticalGuards, "Candidates have different guards") | |
STATISTIC (NonEmptyExitBlock, "Candidate has a non-empty exit block with " "instructions that cannot be moved") | |
STATISTIC (NonEmptyGuardBlock, "Candidate has a non-empty guard block with " "instructions that cannot be moved") | |
STATISTIC (NotRotated, "Candidate is not rotated") | |
STATISTIC (OnlySecondCandidateIsGuarded, "The second candidate is guarded while the first one is not") | |
STATISTIC (NumHoistedInsts, "Number of hoisted preheader instructions.") | |
STATISTIC (NumSunkInsts, "Number of hoisted preheader instructions.") | |
Variables | |
static cl::opt< FusionDependenceAnalysisChoice > | FusionDependenceAnalysis ("loop-fusion-dependence-analysis", cl::desc("Which dependence analysis should loop fusion use?"), cl::values(clEnumValN(FUSION_DEPENDENCE_ANALYSIS_SCEV, "scev", "Use the scalar evolution interface"), clEnumValN(FUSION_DEPENDENCE_ANALYSIS_DA, "da", "Use the dependence analysis interface"), clEnumValN(FUSION_DEPENDENCE_ANALYSIS_ALL, "all", "Use all available analyses")), cl::Hidden, cl::init(FUSION_DEPENDENCE_ANALYSIS_ALL)) |
static cl::opt< unsigned > | FusionPeelMaxCount ("loop-fusion-peel-max-count", cl::init(0), cl::Hidden, cl::desc("Max number of iterations to be peeled from a loop, such that " "fusion can take place")) |
static cl::opt< bool > | VerboseFusionDebugging ("loop-fusion-verbose-debug", cl::desc("Enable verbose debugging for Loop Fusion"), cl::Hidden, cl::init(false)) |
This file implements the loop fusion pass.
The implementation is largely based on the following document:
Code Transformations to Augment the Scope of Loop Fusion in a Production Compiler Christopher Mark Barton MSc Thesis https://webdocs.cs.ualberta.ca/~amaral/thesis/ChristopherBartonMSc.pdf
The general approach taken is to collect sets of control flow equivalent loops and test whether they can be fused. The necessary conditions for fusion are:
This implementation creates FusionCandidates that represent the loop and the necessary information needed by fusion. It then operates on the fusion candidates, first confirming that the candidate is eligible for fusion. The candidates are then collected into control flow equivalent sets, sorted in dominance order. Each set of control flow equivalent candidates is then traversed, attempting to fuse pairs of candidates in the set. If all requirements for fusion are met, the two candidates are fused, creating a new (fused) candidate which is then added back into the set to consider for additional fusion.
This implementation currently does not make any modifications to remove conditions for fusion. Code transformations to make loops conform to each of the conditions for fusion are discussed in more detail in the document above. These can be added to the current implementation in the future.
Definition in file LoopFuse.cpp.
#define DEBUG_TYPE "loop-fusion" |
Definition at line 71 of file LoopFuse.cpp.
Enumerator | |
---|---|
FUSION_DEPENDENCE_ANALYSIS_SCEV | |
FUSION_DEPENDENCE_ANALYSIS_DA | |
FUSION_DEPENDENCE_ANALYSIS_ALL |
Definition at line 105 of file LoopFuse.cpp.
STATISTIC | ( | AddressTakenBB | , |
"Basic block has address taken" | |||
) |
STATISTIC | ( | ContainsVolatileAccess | , |
"Loop contains a volatile access" | |||
) |
STATISTIC | ( | FuseCounter | , |
"Loops fused" | |||
) |
STATISTIC | ( | FusionNotBeneficial | , |
"Fusion is not beneficial" | |||
) |
STATISTIC | ( | InvalidDependencies | , |
"Dependencies prevent fusion" | |||
) |
STATISTIC | ( | InvalidExitBlock | , |
"Loop has invalid exit block" | |||
) |
STATISTIC | ( | InvalidExitingBlock | , |
"Loop has invalid exiting blocks" | |||
) |
STATISTIC | ( | InvalidHeader | , |
"Loop has invalid header" | |||
) |
STATISTIC | ( | InvalidLatch | , |
"Loop has invalid latch" | |||
) |
STATISTIC | ( | InvalidLoop | , |
"Loop is invalid" | |||
) |
STATISTIC | ( | InvalidPreheader | , |
"Loop has invalid preheader" | |||
) |
STATISTIC | ( | MayThrowException | , |
"Loop may throw an exception" | |||
) |
STATISTIC | ( | NonAdjacent | , |
"Loops are not adjacent" | |||
) |
STATISTIC | ( | NonEmptyExitBlock | , |
"Candidate has a non-empty exit block with " "instructions that cannot be moved" | |||
) |
STATISTIC | ( | NonEmptyGuardBlock | , |
"Candidate has a non-empty guard block with " "instructions that cannot be moved" | |||
) |
STATISTIC | ( | NonEmptyPreheader | , |
"Loop has a non-empty preheader with instructions that cannot be moved" | |||
) |
STATISTIC | ( | NonEqualTripCount | , |
"Loop trip counts are not the same" | |||
) |
STATISTIC | ( | NonIdenticalGuards | , |
"Candidates have different guards" | |||
) |
STATISTIC | ( | NotRotated | , |
"Candidate is not rotated" | |||
) |
STATISTIC | ( | NotSimplifiedForm | , |
"Loop is not in simplified form" | |||
) |
STATISTIC | ( | NumFusionCandidates | , |
"Number of candidates for loop fusion" | |||
) |
STATISTIC | ( | NumHoistedInsts | , |
"Number of hoisted preheader instructions." | |||
) |
STATISTIC | ( | NumSunkInsts | , |
"Number of hoisted preheader instructions." | |||
) |
STATISTIC | ( | OnlySecondCandidateIsGuarded | , |
"The second candidate is guarded while the first one is not" | |||
) |
STATISTIC | ( | UncomputableTripCount | , |
"SCEV cannot compute trip count of loop" | |||
) |
STATISTIC | ( | UnknownTripCount | , |
"Loop has unknown trip count" | |||
) |
|
static |
|
static |