1 //===- LoopUnrollAnalyzer.cpp - Unrolling Effect Estimation -----*- 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 file implements UnrolledInstAnalyzer class. It's used for predicting 10 // potential effects that loop unrolling might have, such as enabling constant 11 // propagation and other optimizations. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/Analysis/LoopUnrollAnalyzer.h" 16 #include "llvm/Analysis/LoopInfo.h" 17 18 using namespace llvm; 19 20 /// Try to simplify instruction \param I using its SCEV expression. 21 /// 22 /// The idea is that some AddRec expressions become constants, which then 23 /// could trigger folding of other instructions. However, that only happens 24 /// for expressions whose start value is also constant, which isn't always the 25 /// case. In another common and important case the start value is just some 26 /// address (i.e. SCEVUnknown) - in this case we compute the offset and save 27 /// it along with the base address instead. 28 bool UnrolledInstAnalyzer::simplifyInstWithSCEV(Instruction *I) { 29 if (!SE.isSCEVable(I->getType())) 30 return false; 31 32 const SCEV *S = SE.getSCEV(I); 33 if (auto *SC = dyn_cast<SCEVConstant>(S)) { 34 SimplifiedValues[I] = SC->getValue(); 35 return true; 36 } 37 38 // If we have a loop invariant computation, we only need to compute it once. 39 // Given that, all but the first occurance are free. 40 if (!IterationNumber->isZero() && SE.isLoopInvariant(S, L)) 41 return true; 42 43 auto *AR = dyn_cast<SCEVAddRecExpr>(S); 44 if (!AR || AR->getLoop() != L) 45 return false; 46 47 const SCEV *ValueAtIteration = AR->evaluateAtIteration(IterationNumber, SE); 48 // Check if the AddRec expression becomes a constant. 49 if (auto *SC = dyn_cast<SCEVConstant>(ValueAtIteration)) { 50 SimplifiedValues[I] = SC->getValue(); 51 return true; 52 } 53 54 // Check if the offset from the base address becomes a constant. 55 auto *Base = dyn_cast<SCEVUnknown>(SE.getPointerBase(S)); 56 if (!Base) 57 return false; 58 auto *Offset = 59 dyn_cast<SCEVConstant>(SE.getMinusSCEV(ValueAtIteration, Base)); 60 if (!Offset) 61 return false; 62 SimplifiedAddress Address; 63 Address.Base = Base->getValue(); 64 Address.Offset = Offset->getValue(); 65 SimplifiedAddresses[I] = Address; 66 return false; 67 } 68 69 /// Try to simplify binary operator I. 70 /// 71 /// TODO: Probably it's worth to hoist the code for estimating the 72 /// simplifications effects to a separate class, since we have a very similar 73 /// code in InlineCost already. 74 bool UnrolledInstAnalyzer::visitBinaryOperator(BinaryOperator &I) { 75 Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); 76 if (!isa<Constant>(LHS)) 77 if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS)) 78 LHS = SimpleLHS; 79 if (!isa<Constant>(RHS)) 80 if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS)) 81 RHS = SimpleRHS; 82 83 Value *SimpleV = nullptr; 84 const DataLayout &DL = I.getModule()->getDataLayout(); 85 if (auto FI = dyn_cast<FPMathOperator>(&I)) 86 SimpleV = 87 SimplifyBinOp(I.getOpcode(), LHS, RHS, FI->getFastMathFlags(), DL); 88 else 89 SimpleV = SimplifyBinOp(I.getOpcode(), LHS, RHS, DL); 90 91 if (Constant *C = dyn_cast_or_null<Constant>(SimpleV)) 92 SimplifiedValues[&I] = C; 93 94 if (SimpleV) 95 return true; 96 return Base::visitBinaryOperator(I); 97 } 98 99 /// Try to fold load I. 100 bool UnrolledInstAnalyzer::visitLoad(LoadInst &I) { 101 Value *AddrOp = I.getPointerOperand(); 102 103 auto AddressIt = SimplifiedAddresses.find(AddrOp); 104 if (AddressIt == SimplifiedAddresses.end()) 105 return false; 106 ConstantInt *SimplifiedAddrOp = AddressIt->second.Offset; 107 108 auto *GV = dyn_cast<GlobalVariable>(AddressIt->second.Base); 109 // We're only interested in loads that can be completely folded to a 110 // constant. 111 if (!GV || !GV->hasDefinitiveInitializer() || !GV->isConstant()) 112 return false; 113 114 ConstantDataSequential *CDS = 115 dyn_cast<ConstantDataSequential>(GV->getInitializer()); 116 if (!CDS) 117 return false; 118 119 // We might have a vector load from an array. FIXME: for now we just bail 120 // out in this case, but we should be able to resolve and simplify such 121 // loads. 122 if (CDS->getElementType() != I.getType()) 123 return false; 124 125 unsigned ElemSize = CDS->getElementType()->getPrimitiveSizeInBits() / 8U; 126 if (SimplifiedAddrOp->getValue().getActiveBits() > 64) 127 return false; 128 int64_t SimplifiedAddrOpV = SimplifiedAddrOp->getSExtValue(); 129 if (SimplifiedAddrOpV < 0) { 130 // FIXME: For now we conservatively ignore out of bound accesses, but 131 // we're allowed to perform the optimization in this case. 132 return false; 133 } 134 uint64_t Index = static_cast<uint64_t>(SimplifiedAddrOpV) / ElemSize; 135 if (Index >= CDS->getNumElements()) { 136 // FIXME: For now we conservatively ignore out of bound accesses, but 137 // we're allowed to perform the optimization in this case. 138 return false; 139 } 140 141 Constant *CV = CDS->getElementAsConstant(Index); 142 assert(CV && "Constant expected."); 143 SimplifiedValues[&I] = CV; 144 145 return true; 146 } 147 148 /// Try to simplify cast instruction. 149 bool UnrolledInstAnalyzer::visitCastInst(CastInst &I) { 150 // Propagate constants through casts. 151 Constant *COp = dyn_cast<Constant>(I.getOperand(0)); 152 if (!COp) 153 COp = SimplifiedValues.lookup(I.getOperand(0)); 154 155 // If we know a simplified value for this operand and cast is valid, save the 156 // result to SimplifiedValues. 157 // The cast can be invalid, because SimplifiedValues contains results of SCEV 158 // analysis, which operates on integers (and, e.g., might convert i8* null to 159 // i32 0). 160 if (COp && CastInst::castIsValid(I.getOpcode(), COp, I.getType())) { 161 if (Constant *C = 162 ConstantExpr::getCast(I.getOpcode(), COp, I.getType())) { 163 SimplifiedValues[&I] = C; 164 return true; 165 } 166 } 167 168 return Base::visitCastInst(I); 169 } 170 171 /// Try to simplify cmp instruction. 172 bool UnrolledInstAnalyzer::visitCmpInst(CmpInst &I) { 173 Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); 174 175 // First try to handle simplified comparisons. 176 if (!isa<Constant>(LHS)) 177 if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS)) 178 LHS = SimpleLHS; 179 if (!isa<Constant>(RHS)) 180 if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS)) 181 RHS = SimpleRHS; 182 183 if (!isa<Constant>(LHS) && !isa<Constant>(RHS)) { 184 auto SimplifiedLHS = SimplifiedAddresses.find(LHS); 185 if (SimplifiedLHS != SimplifiedAddresses.end()) { 186 auto SimplifiedRHS = SimplifiedAddresses.find(RHS); 187 if (SimplifiedRHS != SimplifiedAddresses.end()) { 188 SimplifiedAddress &LHSAddr = SimplifiedLHS->second; 189 SimplifiedAddress &RHSAddr = SimplifiedRHS->second; 190 if (LHSAddr.Base == RHSAddr.Base) { 191 LHS = LHSAddr.Offset; 192 RHS = RHSAddr.Offset; 193 } 194 } 195 } 196 } 197 198 if (Constant *CLHS = dyn_cast<Constant>(LHS)) { 199 if (Constant *CRHS = dyn_cast<Constant>(RHS)) { 200 if (CLHS->getType() == CRHS->getType()) { 201 if (Constant *C = ConstantExpr::getCompare(I.getPredicate(), CLHS, CRHS)) { 202 SimplifiedValues[&I] = C; 203 return true; 204 } 205 } 206 } 207 } 208 209 return Base::visitCmpInst(I); 210 } 211 212 bool UnrolledInstAnalyzer::visitPHINode(PHINode &PN) { 213 // Run base visitor first. This way we can gather some useful for later 214 // analysis information. 215 if (Base::visitPHINode(PN)) 216 return true; 217 218 // The loop induction PHI nodes are definitionally free. 219 return PN.getParent() == L->getHeader(); 220 } 221