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/LoopInfo.h" 36 #include "llvm/IR/PassManager.h" 37 #include "llvm/Support/CommandLine.h" 38 #include "llvm/Transforms/Scalar/LoopPassManager.h" 39 40 namespace llvm { 41 42 extern cl::opt<unsigned> SetLicmMssaOptCap; 43 extern cl::opt<unsigned> SetLicmMssaNoAccForPromotionCap; 44 45 /// Performs Loop Invariant Code Motion Pass. 46 class LICMPass : public PassInfoMixin<LICMPass> { 47 unsigned LicmMssaOptCap; 48 unsigned LicmMssaNoAccForPromotionCap; 49 50 public: LICMPass()51 LICMPass() 52 : LicmMssaOptCap(SetLicmMssaOptCap), 53 LicmMssaNoAccForPromotionCap(SetLicmMssaNoAccForPromotionCap) {} LICMPass(unsigned LicmMssaOptCap,unsigned LicmMssaNoAccForPromotionCap)54 LICMPass(unsigned LicmMssaOptCap, unsigned LicmMssaNoAccForPromotionCap) 55 : LicmMssaOptCap(LicmMssaOptCap), 56 LicmMssaNoAccForPromotionCap(LicmMssaNoAccForPromotionCap) {} 57 PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, 58 LoopStandardAnalysisResults &AR, LPMUpdater &U); 59 }; 60 } // end namespace llvm 61 62 #endif // LLVM_TRANSFORMS_SCALAR_LICM_H 63