1//===- LICM.h - Loop Invariant Code Motion Pass -------*- 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// This pass performs loop invariant code motion, attempting to remove as much
10// code from the body of a loop as possible. It does this by either hoisting
11// code into the preheader block, or by sinking code to the exit blocks if it is
12// safe. This pass also promotes must-aliased memory locations in the loop to
13// live in registers, thus hoisting and sinking "invariant" loads and stores.
14//
15// This pass uses alias analysis for two purposes:
16//
17// 1. Moving loop invariant loads and calls out of loops. If we can determine
18// that a load or call inside of a loop never aliases anything stored to,
19// we can hoist it or sink it like any other instruction.
20// 2. Scalar Promotion of Memory - If there is a store instruction inside of
21// the loop, we try to move the store to happen AFTER the loop instead of
22// inside of the loop. This can only happen if a few conditions are true:
23// A. The pointer stored through is loop invariant
24// B. There are no stores or loads in the loop which _may_ alias the
25// pointer. There are no calls in the loop which mod/ref the pointer.
26// If these conditions are true, we can promote the loads and stores in the
27// loop of the pointer to use a temporary alloca'd variable. We then use
28// the SSAUpdater to construct the appropriate SSA form for the value.
29//
30//===----------------------------------------------------------------------===//
31
32#ifndef LLVM_TRANSFORMS_SCALAR_LICM_H
33#define LLVM_TRANSFORMS_SCALAR_LICM_H
34
35#include "llvm/Analysis/LoopAnalysisManager.h"
36#include "llvm/IR/PassManager.h"
37#include "llvm/Support/CommandLine.h"
38
39namespace llvm {
40
41class LPMUpdater;
42class Loop;
43class LoopNest;
44
45extern cl::opt<unsigned> SetLicmMssaOptCap;
46extern cl::opt<unsigned> SetLicmMssaNoAccForPromotionCap;
47
48struct LICMOptions {
49 unsigned MssaOptCap;
50 unsigned MssaNoAccForPromotionCap;
51 bool AllowSpeculation;
52
53 LICMOptions()
54 : MssaOptCap(SetLicmMssaOptCap),
55 MssaNoAccForPromotionCap(SetLicmMssaNoAccForPromotionCap),
56 AllowSpeculation(true) {}
57
58 LICMOptions(unsigned MssaOptCap, unsigned MssaNoAccForPromotionCap,
59 bool AllowSpeculation)
60 : MssaOptCap(MssaOptCap),
61 MssaNoAccForPromotionCap(MssaNoAccForPromotionCap),
62 AllowSpeculation(AllowSpeculation) {}
63};
64
65/// Performs Loop Invariant Code Motion Pass.
66class LICMPass : public PassInfoMixin<LICMPass> {
67 LICMOptions Opts;
68
69public:
70 LICMPass(unsigned MssaOptCap, unsigned MssaNoAccForPromotionCap,
71 bool AllowSpeculation)
72 : LICMPass(LICMOptions(MssaOptCap, MssaNoAccForPromotionCap,
73 AllowSpeculation)) {}
74 LICMPass(LICMOptions Opts) : Opts(Opts) {}
75
76 PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
77 LoopStandardAnalysisResults &AR, LPMUpdater &U);
78
79 void printPipeline(raw_ostream &OS,
80 function_ref<StringRef(StringRef)> MapClassName2PassName);
81};
82
83/// Performs LoopNest Invariant Code Motion Pass.
84class LNICMPass : public PassInfoMixin<LNICMPass> {
85 LICMOptions Opts;
86
87public:
88 LNICMPass(unsigned MssaOptCap, unsigned MssaNoAccForPromotionCap,
89 bool AllowSpeculation)
90 : LNICMPass(LICMOptions(MssaOptCap, MssaNoAccForPromotionCap,
91 AllowSpeculation)) {}
92 LNICMPass(LICMOptions Opts) : Opts(Opts) {}
93
94 PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &AM,
95 LoopStandardAnalysisResults &AR, LPMUpdater &U);
96
97 void printPipeline(raw_ostream &OS,
98 function_ref<StringRef(StringRef)> MapClassName2PassName);
99};
100} // end namespace llvm
101
102#endif // LLVM_TRANSFORMS_SCALAR_LICM_H
103

source code of llvm/include/llvm/Transforms/Scalar/LICM.h