LLVM API Documentation
00001 //===-- AArch64AddressTypePromotion.cpp --- Promote type for addr accesses -==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This pass tries to promote the computations use to obtained a sign extended 00011 // value used into memory accesses. 00012 // E.g. 00013 // a = add nsw i32 b, 3 00014 // d = sext i32 a to i64 00015 // e = getelementptr ..., i64 d 00016 // 00017 // => 00018 // f = sext i32 b to i64 00019 // a = add nsw i64 f, 3 00020 // e = getelementptr ..., i64 a 00021 // 00022 // This is legal to do if the computations are marked with either nsw or nuw 00023 // markers. 00024 // Moreover, the current heuristic is simple: it does not create new sext 00025 // operations, i.e., it gives up when a sext would have forked (e.g., if 00026 // a = add i32 b, c, two sexts are required to promote the computation). 00027 // 00028 // FIXME: This pass may be useful for other targets too. 00029 // ===---------------------------------------------------------------------===// 00030 00031 #include "AArch64.h" 00032 #include "llvm/ADT/DenseMap.h" 00033 #include "llvm/ADT/SmallPtrSet.h" 00034 #include "llvm/ADT/SmallVector.h" 00035 #include "llvm/IR/Constants.h" 00036 #include "llvm/IR/Dominators.h" 00037 #include "llvm/IR/Function.h" 00038 #include "llvm/IR/Instructions.h" 00039 #include "llvm/IR/Module.h" 00040 #include "llvm/IR/Operator.h" 00041 #include "llvm/Pass.h" 00042 #include "llvm/Support/CommandLine.h" 00043 #include "llvm/Support/Debug.h" 00044 00045 using namespace llvm; 00046 00047 #define DEBUG_TYPE "aarch64-type-promotion" 00048 00049 static cl::opt<bool> 00050 EnableAddressTypePromotion("aarch64-type-promotion", cl::Hidden, 00051 cl::desc("Enable the type promotion pass"), 00052 cl::init(true)); 00053 static cl::opt<bool> 00054 EnableMerge("aarch64-type-promotion-merge", cl::Hidden, 00055 cl::desc("Enable merging of redundant sexts when one is dominating" 00056 " the other."), 00057 cl::init(true)); 00058 00059 //===----------------------------------------------------------------------===// 00060 // AArch64AddressTypePromotion 00061 //===----------------------------------------------------------------------===// 00062 00063 namespace llvm { 00064 void initializeAArch64AddressTypePromotionPass(PassRegistry &); 00065 } 00066 00067 namespace { 00068 class AArch64AddressTypePromotion : public FunctionPass { 00069 00070 public: 00071 static char ID; 00072 AArch64AddressTypePromotion() 00073 : FunctionPass(ID), Func(nullptr), ConsideredSExtType(nullptr) { 00074 initializeAArch64AddressTypePromotionPass(*PassRegistry::getPassRegistry()); 00075 } 00076 00077 const char *getPassName() const override { 00078 return "AArch64 Address Type Promotion"; 00079 } 00080 00081 /// Iterate over the functions and promote the computation of interesting 00082 // sext instructions. 00083 bool runOnFunction(Function &F) override; 00084 00085 private: 00086 /// The current function. 00087 Function *Func; 00088 /// Filter out all sexts that does not have this type. 00089 /// Currently initialized with Int64Ty. 00090 Type *ConsideredSExtType; 00091 00092 // This transformation requires dominator info. 00093 void getAnalysisUsage(AnalysisUsage &AU) const override { 00094 AU.setPreservesCFG(); 00095 AU.addRequired<DominatorTreeWrapperPass>(); 00096 AU.addPreserved<DominatorTreeWrapperPass>(); 00097 FunctionPass::getAnalysisUsage(AU); 00098 } 00099 00100 typedef SmallPtrSet<Instruction *, 32> SetOfInstructions; 00101 typedef SmallVector<Instruction *, 16> Instructions; 00102 typedef DenseMap<Value *, Instructions> ValueToInsts; 00103 00104 /// Check if it is profitable to move a sext through this instruction. 00105 /// Currently, we consider it is profitable if: 00106 /// - Inst is used only once (no need to insert truncate). 00107 /// - Inst has only one operand that will require a sext operation (we do 00108 /// do not create new sext operation). 00109 bool shouldGetThrough(const Instruction *Inst); 00110 00111 /// Check if it is possible and legal to move a sext through this 00112 /// instruction. 00113 /// Current heuristic considers that we can get through: 00114 /// - Arithmetic operation marked with the nsw or nuw flag. 00115 /// - Other sext operation. 00116 /// - Truncate operation if it was just dropping sign extended bits. 00117 bool canGetThrough(const Instruction *Inst); 00118 00119 /// Move sext operations through safe to sext instructions. 00120 bool propagateSignExtension(Instructions &SExtInsts); 00121 00122 /// Is this sext should be considered for code motion. 00123 /// We look for sext with ConsideredSExtType and uses in at least one 00124 // GetElementPtrInst. 00125 bool shouldConsiderSExt(const Instruction *SExt) const; 00126 00127 /// Collect all interesting sext operations, i.e., the ones with the right 00128 /// type and used in memory accesses. 00129 /// More precisely, a sext instruction is considered as interesting if it 00130 /// is used in a "complex" getelementptr or it exits at least another 00131 /// sext instruction that sign extended the same initial value. 00132 /// A getelementptr is considered as "complex" if it has more than 2 00133 // operands. 00134 void analyzeSExtension(Instructions &SExtInsts); 00135 00136 /// Merge redundant sign extension operations in common dominator. 00137 void mergeSExts(ValueToInsts &ValToSExtendedUses, 00138 SetOfInstructions &ToRemove); 00139 }; 00140 } // end anonymous namespace. 00141 00142 char AArch64AddressTypePromotion::ID = 0; 00143 00144 INITIALIZE_PASS_BEGIN(AArch64AddressTypePromotion, "aarch64-type-promotion", 00145 "AArch64 Type Promotion Pass", false, false) 00146 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 00147 INITIALIZE_PASS_END(AArch64AddressTypePromotion, "aarch64-type-promotion", 00148 "AArch64 Type Promotion Pass", false, false) 00149 00150 FunctionPass *llvm::createAArch64AddressTypePromotionPass() { 00151 return new AArch64AddressTypePromotion(); 00152 } 00153 00154 bool AArch64AddressTypePromotion::canGetThrough(const Instruction *Inst) { 00155 if (isa<SExtInst>(Inst)) 00156 return true; 00157 00158 const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Inst); 00159 if (BinOp && isa<OverflowingBinaryOperator>(BinOp) && 00160 (BinOp->hasNoUnsignedWrap() || BinOp->hasNoSignedWrap())) 00161 return true; 00162 00163 // sext(trunc(sext)) --> sext 00164 if (isa<TruncInst>(Inst) && isa<SExtInst>(Inst->getOperand(0))) { 00165 const Instruction *Opnd = cast<Instruction>(Inst->getOperand(0)); 00166 // Check that the truncate just drop sign extended bits. 00167 if (Inst->getType()->getIntegerBitWidth() >= 00168 Opnd->getOperand(0)->getType()->getIntegerBitWidth() && 00169 Inst->getOperand(0)->getType()->getIntegerBitWidth() <= 00170 ConsideredSExtType->getIntegerBitWidth()) 00171 return true; 00172 } 00173 00174 return false; 00175 } 00176 00177 bool AArch64AddressTypePromotion::shouldGetThrough(const Instruction *Inst) { 00178 // If the type of the sext is the same as the considered one, this sext 00179 // will become useless. 00180 // Otherwise, we will have to do something to preserve the original value, 00181 // unless it is used once. 00182 if (isa<SExtInst>(Inst) && 00183 (Inst->getType() == ConsideredSExtType || Inst->hasOneUse())) 00184 return true; 00185 00186 // If the Inst is used more that once, we may need to insert truncate 00187 // operations and we don't do that at the moment. 00188 if (!Inst->hasOneUse()) 00189 return false; 00190 00191 // This truncate is used only once, thus if we can get thourgh, it will become 00192 // useless. 00193 if (isa<TruncInst>(Inst)) 00194 return true; 00195 00196 // If both operands are not constant, a new sext will be created here. 00197 // Current heuristic is: each step should be profitable. 00198 // Therefore we don't allow to increase the number of sext even if it may 00199 // be profitable later on. 00200 if (isa<BinaryOperator>(Inst) && isa<ConstantInt>(Inst->getOperand(1))) 00201 return true; 00202 00203 return false; 00204 } 00205 00206 static bool shouldSExtOperand(const Instruction *Inst, int OpIdx) { 00207 if (isa<SelectInst>(Inst) && OpIdx == 0) 00208 return false; 00209 return true; 00210 } 00211 00212 bool 00213 AArch64AddressTypePromotion::shouldConsiderSExt(const Instruction *SExt) const { 00214 if (SExt->getType() != ConsideredSExtType) 00215 return false; 00216 00217 for (const User *U : SExt->users()) { 00218 if (isa<GetElementPtrInst>(U)) 00219 return true; 00220 } 00221 00222 return false; 00223 } 00224 00225 // Input: 00226 // - SExtInsts contains all the sext instructions that are used directly in 00227 // GetElementPtrInst, i.e., access to memory. 00228 // Algorithm: 00229 // - For each sext operation in SExtInsts: 00230 // Let var be the operand of sext. 00231 // while it is profitable (see shouldGetThrough), legal, and safe 00232 // (see canGetThrough) to move sext through var's definition: 00233 // * promote the type of var's definition. 00234 // * fold var into sext uses. 00235 // * move sext above var's definition. 00236 // * update sext operand to use the operand of var that should be sign 00237 // extended (by construction there is only one). 00238 // 00239 // E.g., 00240 // a = ... i32 c, 3 00241 // b = sext i32 a to i64 <- is it legal/safe/profitable to get through 'a' 00242 // ... 00243 // = b 00244 // => Yes, update the code 00245 // b = sext i32 c to i64 00246 // a = ... i64 b, 3 00247 // ... 00248 // = a 00249 // Iterate on 'c'. 00250 bool 00251 AArch64AddressTypePromotion::propagateSignExtension(Instructions &SExtInsts) { 00252 DEBUG(dbgs() << "*** Propagate Sign Extension ***\n"); 00253 00254 bool LocalChange = false; 00255 SetOfInstructions ToRemove; 00256 ValueToInsts ValToSExtendedUses; 00257 while (!SExtInsts.empty()) { 00258 // Get through simple chain. 00259 Instruction *SExt = SExtInsts.pop_back_val(); 00260 00261 DEBUG(dbgs() << "Consider:\n" << *SExt << '\n'); 00262 00263 // If this SExt has already been merged continue. 00264 if (SExt->use_empty() && ToRemove.count(SExt)) { 00265 DEBUG(dbgs() << "No uses => marked as delete\n"); 00266 continue; 00267 } 00268 00269 // Now try to get through the chain of definitions. 00270 while (auto *Inst = dyn_cast<Instruction>(SExt->getOperand(0))) { 00271 DEBUG(dbgs() << "Try to get through:\n" << *Inst << '\n'); 00272 if (!canGetThrough(Inst) || !shouldGetThrough(Inst)) { 00273 // We cannot get through something that is not an Instruction 00274 // or not safe to SExt. 00275 DEBUG(dbgs() << "Cannot get through\n"); 00276 break; 00277 } 00278 00279 LocalChange = true; 00280 // If this is a sign extend, it becomes useless. 00281 if (isa<SExtInst>(Inst) || isa<TruncInst>(Inst)) { 00282 DEBUG(dbgs() << "SExt or trunc, mark it as to remove\n"); 00283 // We cannot use replaceAllUsesWith here because we may trigger some 00284 // assertion on the type as all involved sext operation may have not 00285 // been moved yet. 00286 while (!Inst->use_empty()) { 00287 Use &U = *Inst->use_begin(); 00288 Instruction *User = dyn_cast<Instruction>(U.getUser()); 00289 assert(User && "User of sext is not an Instruction!"); 00290 User->setOperand(U.getOperandNo(), SExt); 00291 } 00292 ToRemove.insert(Inst); 00293 SExt->setOperand(0, Inst->getOperand(0)); 00294 SExt->moveBefore(Inst); 00295 continue; 00296 } 00297 00298 // Get through the Instruction: 00299 // 1. Update its type. 00300 // 2. Replace the uses of SExt by Inst. 00301 // 3. Sign extend each operand that needs to be sign extended. 00302 00303 // Step #1. 00304 Inst->mutateType(SExt->getType()); 00305 // Step #2. 00306 SExt->replaceAllUsesWith(Inst); 00307 // Step #3. 00308 Instruction *SExtForOpnd = SExt; 00309 00310 DEBUG(dbgs() << "Propagate SExt to operands\n"); 00311 for (int OpIdx = 0, EndOpIdx = Inst->getNumOperands(); OpIdx != EndOpIdx; 00312 ++OpIdx) { 00313 DEBUG(dbgs() << "Operand:\n" << *(Inst->getOperand(OpIdx)) << '\n'); 00314 if (Inst->getOperand(OpIdx)->getType() == SExt->getType() || 00315 !shouldSExtOperand(Inst, OpIdx)) { 00316 DEBUG(dbgs() << "No need to propagate\n"); 00317 continue; 00318 } 00319 // Check if we can statically sign extend the operand. 00320 Value *Opnd = Inst->getOperand(OpIdx); 00321 if (const ConstantInt *Cst = dyn_cast<ConstantInt>(Opnd)) { 00322 DEBUG(dbgs() << "Statically sign extend\n"); 00323 Inst->setOperand(OpIdx, ConstantInt::getSigned(SExt->getType(), 00324 Cst->getSExtValue())); 00325 continue; 00326 } 00327 // UndefValue are typed, so we have to statically sign extend them. 00328 if (isa<UndefValue>(Opnd)) { 00329 DEBUG(dbgs() << "Statically sign extend\n"); 00330 Inst->setOperand(OpIdx, UndefValue::get(SExt->getType())); 00331 continue; 00332 } 00333 00334 // Otherwise we have to explicity sign extend it. 00335 assert(SExtForOpnd && 00336 "Only one operand should have been sign extended"); 00337 00338 SExtForOpnd->setOperand(0, Opnd); 00339 00340 DEBUG(dbgs() << "Move before:\n" << *Inst << "\nSign extend\n"); 00341 // Move the sign extension before the insertion point. 00342 SExtForOpnd->moveBefore(Inst); 00343 Inst->setOperand(OpIdx, SExtForOpnd); 00344 // If more sext are required, new instructions will have to be created. 00345 SExtForOpnd = nullptr; 00346 } 00347 if (SExtForOpnd == SExt) { 00348 DEBUG(dbgs() << "Sign extension is useless now\n"); 00349 ToRemove.insert(SExt); 00350 break; 00351 } 00352 } 00353 00354 // If the use is already of the right type, connect its uses to its argument 00355 // and delete it. 00356 // This can happen for an Instruction all uses of which are sign extended. 00357 if (!ToRemove.count(SExt) && 00358 SExt->getType() == SExt->getOperand(0)->getType()) { 00359 DEBUG(dbgs() << "Sign extension is useless, attach its use to " 00360 "its argument\n"); 00361 SExt->replaceAllUsesWith(SExt->getOperand(0)); 00362 ToRemove.insert(SExt); 00363 } else 00364 ValToSExtendedUses[SExt->getOperand(0)].push_back(SExt); 00365 } 00366 00367 if (EnableMerge) 00368 mergeSExts(ValToSExtendedUses, ToRemove); 00369 00370 // Remove all instructions marked as ToRemove. 00371 for (Instruction *I: ToRemove) 00372 I->eraseFromParent(); 00373 return LocalChange; 00374 } 00375 00376 void AArch64AddressTypePromotion::mergeSExts(ValueToInsts &ValToSExtendedUses, 00377 SetOfInstructions &ToRemove) { 00378 DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 00379 00380 for (auto &Entry : ValToSExtendedUses) { 00381 Instructions &Insts = Entry.second; 00382 Instructions CurPts; 00383 for (Instruction *Inst : Insts) { 00384 if (ToRemove.count(Inst)) 00385 continue; 00386 bool inserted = false; 00387 for (auto &Pt : CurPts) { 00388 if (DT.dominates(Inst, Pt)) { 00389 DEBUG(dbgs() << "Replace all uses of:\n" << *Pt << "\nwith:\n" 00390 << *Inst << '\n'); 00391 Pt->replaceAllUsesWith(Inst); 00392 ToRemove.insert(Pt); 00393 Pt = Inst; 00394 inserted = true; 00395 break; 00396 } 00397 if (!DT.dominates(Pt, Inst)) 00398 // Give up if we need to merge in a common dominator as the 00399 // expermients show it is not profitable. 00400 continue; 00401 00402 DEBUG(dbgs() << "Replace all uses of:\n" << *Inst << "\nwith:\n" 00403 << *Pt << '\n'); 00404 Inst->replaceAllUsesWith(Pt); 00405 ToRemove.insert(Inst); 00406 inserted = true; 00407 break; 00408 } 00409 if (!inserted) 00410 CurPts.push_back(Inst); 00411 } 00412 } 00413 } 00414 00415 void AArch64AddressTypePromotion::analyzeSExtension(Instructions &SExtInsts) { 00416 DEBUG(dbgs() << "*** Analyze Sign Extensions ***\n"); 00417 00418 DenseMap<Value *, Instruction *> SeenChains; 00419 00420 for (auto &BB : *Func) { 00421 for (auto &II : BB) { 00422 Instruction *SExt = &II; 00423 00424 // Collect all sext operation per type. 00425 if (!isa<SExtInst>(SExt) || !shouldConsiderSExt(SExt)) 00426 continue; 00427 00428 DEBUG(dbgs() << "Found:\n" << (*SExt) << '\n'); 00429 00430 // Cases where we actually perform the optimization: 00431 // 1. SExt is used in a getelementptr with more than 2 operand => 00432 // likely we can merge some computation if they are done on 64 bits. 00433 // 2. The beginning of the SExt chain is SExt several time. => 00434 // code sharing is possible. 00435 00436 bool insert = false; 00437 // #1. 00438 for (const User *U : SExt->users()) { 00439 const Instruction *Inst = dyn_cast<GetElementPtrInst>(U); 00440 if (Inst && Inst->getNumOperands() > 2) { 00441 DEBUG(dbgs() << "Interesting use in GetElementPtrInst\n" << *Inst 00442 << '\n'); 00443 insert = true; 00444 break; 00445 } 00446 } 00447 00448 // #2. 00449 // Check the head of the chain. 00450 Instruction *Inst = SExt; 00451 Value *Last; 00452 do { 00453 int OpdIdx = 0; 00454 const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Inst); 00455 if (BinOp && isa<ConstantInt>(BinOp->getOperand(0))) 00456 OpdIdx = 1; 00457 Last = Inst->getOperand(OpdIdx); 00458 Inst = dyn_cast<Instruction>(Last); 00459 } while (Inst && canGetThrough(Inst) && shouldGetThrough(Inst)); 00460 00461 DEBUG(dbgs() << "Head of the chain:\n" << *Last << '\n'); 00462 DenseMap<Value *, Instruction *>::iterator AlreadySeen = 00463 SeenChains.find(Last); 00464 if (insert || AlreadySeen != SeenChains.end()) { 00465 DEBUG(dbgs() << "Insert\n"); 00466 SExtInsts.push_back(SExt); 00467 if (AlreadySeen != SeenChains.end() && AlreadySeen->second != nullptr) { 00468 DEBUG(dbgs() << "Insert chain member\n"); 00469 SExtInsts.push_back(AlreadySeen->second); 00470 SeenChains[Last] = nullptr; 00471 } 00472 } else { 00473 DEBUG(dbgs() << "Record its chain membership\n"); 00474 SeenChains[Last] = SExt; 00475 } 00476 } 00477 } 00478 } 00479 00480 bool AArch64AddressTypePromotion::runOnFunction(Function &F) { 00481 if (!EnableAddressTypePromotion || F.isDeclaration()) 00482 return false; 00483 Func = &F; 00484 ConsideredSExtType = Type::getInt64Ty(Func->getContext()); 00485 00486 DEBUG(dbgs() << "*** " << getPassName() << ": " << Func->getName() << '\n'); 00487 00488 Instructions SExtInsts; 00489 analyzeSExtension(SExtInsts); 00490 return propagateSignExtension(SExtInsts); 00491 }