1 //===- ConstantHoisting.cpp - Prepare code for expensive constants --------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This pass identifies expensive constants to hoist and coalesces them to 11 // better prepare it for SelectionDAG-based code generation. This works around 12 // the limitations of the basic-block-at-a-time approach. 13 // 14 // First it scans all instructions for integer constants and calculates its 15 // cost. If the constant can be folded into the instruction (the cost is 16 // TCC_Free) or the cost is just a simple operation (TCC_BASIC), then we don't 17 // consider it expensive and leave it alone. This is the default behavior and 18 // the default implementation of getIntImmCost will always return TCC_Free. 19 // 20 // If the cost is more than TCC_BASIC, then the integer constant can't be folded 21 // into the instruction and it might be beneficial to hoist the constant. 22 // Similar constants are coalesced to reduce register pressure and 23 // materialization code. 24 // 25 // When a constant is hoisted, it is also hidden behind a bitcast to force it to 26 // be live-out of the basic block. Otherwise the constant would be just 27 // duplicated and each basic block would have its own copy in the SelectionDAG. 28 // The SelectionDAG recognizes such constants as opaque and doesn't perform 29 // certain transformations on them, which would create a new expensive constant. 30 // 31 // This optimization is only applied to integer constants in instructions and 32 // simple (this means not nested) constant cast expressions. For example: 33 // %0 = load i64* inttoptr (i64 big_constant to i64*) 34 //===----------------------------------------------------------------------===// 35 36 #include "llvm/Transforms/Scalar.h" 37 #include "llvm/ADT/SmallSet.h" 38 #include "llvm/ADT/SmallVector.h" 39 #include "llvm/ADT/Statistic.h" 40 #include "llvm/Analysis/TargetTransformInfo.h" 41 #include "llvm/IR/Constants.h" 42 #include "llvm/IR/Dominators.h" 43 #include "llvm/IR/IntrinsicInst.h" 44 #include "llvm/Pass.h" 45 #include "llvm/Support/Debug.h" 46 47 using namespace llvm; 48 49 #define DEBUG_TYPE "consthoist" 50 51 STATISTIC(NumConstantsHoisted, "Number of constants hoisted"); 52 STATISTIC(NumConstantsRebased, "Number of constants rebased"); 53 54 namespace { 55 struct ConstantUser; 56 struct RebasedConstantInfo; 57 58 typedef SmallVector<ConstantUser, 8> ConstantUseListType; 59 typedef SmallVector<RebasedConstantInfo, 4> RebasedConstantListType; 60 61 /// \brief Keeps track of the user of a constant and the operand index where the 62 /// constant is used. 63 struct ConstantUser { 64 Instruction *Inst; 65 unsigned OpndIdx; 66 67 ConstantUser(Instruction *Inst, unsigned Idx) : Inst(Inst), OpndIdx(Idx) { } 68 }; 69 70 /// \brief Keeps track of a constant candidate and its uses. 71 struct ConstantCandidate { 72 ConstantUseListType Uses; 73 ConstantInt *ConstInt; 74 unsigned CumulativeCost; 75 76 ConstantCandidate(ConstantInt *ConstInt) 77 : ConstInt(ConstInt), CumulativeCost(0) { } 78 79 /// \brief Add the user to the use list and update the cost. 80 void addUser(Instruction *Inst, unsigned Idx, unsigned Cost) { 81 CumulativeCost += Cost; 82 Uses.push_back(ConstantUser(Inst, Idx)); 83 } 84 }; 85 86 /// \brief This represents a constant that has been rebased with respect to a 87 /// base constant. The difference to the base constant is recorded in Offset. 88 struct RebasedConstantInfo { 89 ConstantUseListType Uses; 90 Constant *Offset; 91 92 RebasedConstantInfo(ConstantUseListType &&Uses, Constant *Offset) 93 : Uses(Uses), Offset(Offset) { } 94 }; 95 96 /// \brief A base constant and all its rebased constants. 97 struct ConstantInfo { 98 ConstantInt *BaseConstant; 99 RebasedConstantListType RebasedConstants; 100 }; 101 102 /// \brief The constant hoisting pass. 103 class ConstantHoisting : public FunctionPass { 104 typedef DenseMap<ConstantInt *, unsigned> ConstCandMapType; 105 typedef std::vector<ConstantCandidate> ConstCandVecType; 106 107 const TargetTransformInfo *TTI; 108 DominatorTree *DT; 109 BasicBlock *Entry; 110 111 /// Keeps track of constant candidates found in the function. 112 ConstCandVecType ConstCandVec; 113 114 /// Keep track of cast instructions we already cloned. 115 SmallDenseMap<Instruction *, Instruction *> ClonedCastMap; 116 117 /// These are the final constants we decided to hoist. 118 SmallVector<ConstantInfo, 8> ConstantVec; 119 public: 120 static char ID; // Pass identification, replacement for typeid 121 ConstantHoisting() : FunctionPass(ID), TTI(0), DT(0), Entry(0) { 122 initializeConstantHoistingPass(*PassRegistry::getPassRegistry()); 123 } 124 125 bool runOnFunction(Function &Fn) override; 126 127 const char *getPassName() const override { return "Constant Hoisting"; } 128 129 void getAnalysisUsage(AnalysisUsage &AU) const override { 130 AU.setPreservesCFG(); 131 AU.addRequired<DominatorTreeWrapperPass>(); 132 AU.addRequired<TargetTransformInfo>(); 133 } 134 135 private: 136 /// \brief Initialize the pass. 137 void setup(Function &Fn) { 138 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 139 TTI = &getAnalysis<TargetTransformInfo>(); 140 Entry = &Fn.getEntryBlock(); 141 } 142 143 /// \brief Cleanup. 144 void cleanup() { 145 ConstantVec.clear(); 146 ClonedCastMap.clear(); 147 ConstCandVec.clear(); 148 149 TTI = nullptr; 150 DT = nullptr; 151 Entry = nullptr; 152 } 153 154 Instruction *findMatInsertPt(Instruction *Inst, unsigned Idx = ~0U) const; 155 Instruction *findConstantInsertionPoint(const ConstantInfo &ConstInfo) const; 156 void collectConstantCandidates(ConstCandMapType &ConstCandMap, 157 Instruction *Inst, unsigned Idx, 158 ConstantInt *ConstInt); 159 void collectConstantCandidates(ConstCandMapType &ConstCandMap, 160 Instruction *Inst); 161 void collectConstantCandidates(Function &Fn); 162 void findAndMakeBaseConstant(ConstCandVecType::iterator S, 163 ConstCandVecType::iterator E); 164 void findBaseConstants(); 165 void emitBaseConstants(Instruction *Base, Constant *Offset, 166 const ConstantUser &ConstUser); 167 bool emitBaseConstants(); 168 void deleteDeadCastInst() const; 169 bool optimizeConstants(Function &Fn); 170 }; 171 } 172 173 char ConstantHoisting::ID = 0; 174 INITIALIZE_PASS_BEGIN(ConstantHoisting, "consthoist", "Constant Hoisting", 175 false, false) 176 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 177 INITIALIZE_AG_DEPENDENCY(TargetTransformInfo) 178 INITIALIZE_PASS_END(ConstantHoisting, "consthoist", "Constant Hoisting", 179 false, false) 180 181 FunctionPass *llvm::createConstantHoistingPass() { 182 return new ConstantHoisting(); 183 } 184 185 /// \brief Perform the constant hoisting optimization for the given function. 186 bool ConstantHoisting::runOnFunction(Function &Fn) { 187 DEBUG(dbgs() << "********** Begin Constant Hoisting **********\n"); 188 DEBUG(dbgs() << "********** Function: " << Fn.getName() << '\n'); 189 190 setup(Fn); 191 192 bool MadeChange = optimizeConstants(Fn); 193 194 if (MadeChange) { 195 DEBUG(dbgs() << "********** Function after Constant Hoisting: " 196 << Fn.getName() << '\n'); 197 DEBUG(dbgs() << Fn); 198 } 199 DEBUG(dbgs() << "********** End Constant Hoisting **********\n"); 200 201 cleanup(); 202 203 return MadeChange; 204 } 205 206 207 /// \brief Find the constant materialization insertion point. 208 Instruction *ConstantHoisting::findMatInsertPt(Instruction *Inst, 209 unsigned Idx) const { 210 // If the operand is a cast instruction, then we have to materialize the 211 // constant before the cast instruction. 212 if (Idx != ~0U) { 213 Value *Opnd = Inst->getOperand(Idx); 214 if (auto CastInst = dyn_cast<Instruction>(Opnd)) 215 if (CastInst->isCast()) 216 return CastInst; 217 } 218 219 // The simple and common case. This also includes constant expressions. 220 if (!isa<PHINode>(Inst) && !isa<LandingPadInst>(Inst)) 221 return Inst; 222 223 // We can't insert directly before a phi node or landing pad. Insert before 224 // the terminator of the incoming or dominating block. 225 assert(Entry != Inst->getParent() && "PHI or landing pad in entry block!"); 226 if (Idx != ~0U && isa<PHINode>(Inst)) 227 return cast<PHINode>(Inst)->getIncomingBlock(Idx)->getTerminator(); 228 229 BasicBlock *IDom = DT->getNode(Inst->getParent())->getIDom()->getBlock(); 230 return IDom->getTerminator(); 231 } 232 233 /// \brief Find an insertion point that dominates all uses. 234 Instruction *ConstantHoisting:: 235 findConstantInsertionPoint(const ConstantInfo &ConstInfo) const { 236 assert(!ConstInfo.RebasedConstants.empty() && "Invalid constant info entry."); 237 // Collect all basic blocks. 238 SmallPtrSet<BasicBlock *, 8> BBs; 239 for (auto const &RCI : ConstInfo.RebasedConstants) 240 for (auto const &U : RCI.Uses) 241 BBs.insert(findMatInsertPt(U.Inst, U.OpndIdx)->getParent()); 242 243 if (BBs.count(Entry)) 244 return &Entry->front(); 245 246 while (BBs.size() >= 2) { 247 BasicBlock *BB, *BB1, *BB2; 248 BB1 = *BBs.begin(); 249 BB2 = *std::next(BBs.begin()); 250 BB = DT->findNearestCommonDominator(BB1, BB2); 251 if (BB == Entry) 252 return &Entry->front(); 253 BBs.erase(BB1); 254 BBs.erase(BB2); 255 BBs.insert(BB); 256 } 257 assert((BBs.size() == 1) && "Expected only one element."); 258 Instruction &FirstInst = (*BBs.begin())->front(); 259 return findMatInsertPt(&FirstInst); 260 } 261 262 263 /// \brief Record constant integer ConstInt for instruction Inst at operand 264 /// index Idx. 265 /// 266 /// The operand at index Idx is not necessarily the constant integer itself. It 267 /// could also be a cast instruction or a constant expression that uses the 268 // constant integer. 269 void ConstantHoisting::collectConstantCandidates(ConstCandMapType &ConstCandMap, 270 Instruction *Inst, 271 unsigned Idx, 272 ConstantInt *ConstInt) { 273 unsigned Cost; 274 // Ask the target about the cost of materializing the constant for the given 275 // instruction and operand index. 276 if (auto IntrInst = dyn_cast<IntrinsicInst>(Inst)) 277 Cost = TTI->getIntImmCost(IntrInst->getIntrinsicID(), Idx, 278 ConstInt->getValue(), ConstInt->getType()); 279 else 280 Cost = TTI->getIntImmCost(Inst->getOpcode(), Idx, ConstInt->getValue(), 281 ConstInt->getType()); 282 283 // Ignore cheap integer constants. 284 if (Cost > TargetTransformInfo::TCC_Basic) { 285 ConstCandMapType::iterator Itr; 286 bool Inserted; 287 std::tie(Itr, Inserted) = ConstCandMap.insert(std::make_pair(ConstInt, 0)); 288 if (Inserted) { 289 ConstCandVec.push_back(ConstantCandidate(ConstInt)); 290 Itr->second = ConstCandVec.size() - 1; 291 } 292 ConstCandVec[Itr->second].addUser(Inst, Idx, Cost); 293 DEBUG(if (isa<ConstantInt>(Inst->getOperand(Idx))) 294 dbgs() << "Collect constant " << *ConstInt << " from " << *Inst 295 << " with cost " << Cost << '\n'; 296 else 297 dbgs() << "Collect constant " << *ConstInt << " indirectly from " 298 << *Inst << " via " << *Inst->getOperand(Idx) << " with cost " 299 << Cost << '\n'; 300 ); 301 } 302 } 303 304 /// \brief Scan the instruction for expensive integer constants and record them 305 /// in the constant candidate vector. 306 void ConstantHoisting::collectConstantCandidates(ConstCandMapType &ConstCandMap, 307 Instruction *Inst) { 308 // Skip all cast instructions. They are visited indirectly later on. 309 if (Inst->isCast()) 310 return; 311 312 // Can't handle inline asm. Skip it. 313 if (auto Call = dyn_cast<CallInst>(Inst)) 314 if (isa<InlineAsm>(Call->getCalledValue())) 315 return; 316 317 // Scan all operands. 318 for (unsigned Idx = 0, E = Inst->getNumOperands(); Idx != E; ++Idx) { 319 Value *Opnd = Inst->getOperand(Idx); 320 321 // Visit constant integers. 322 if (auto ConstInt = dyn_cast<ConstantInt>(Opnd)) { 323 collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); 324 continue; 325 } 326 327 // Visit cast instructions that have constant integers. 328 if (auto CastInst = dyn_cast<Instruction>(Opnd)) { 329 // Only visit cast instructions, which have been skipped. All other 330 // instructions should have already been visited. 331 if (!CastInst->isCast()) 332 continue; 333 334 if (auto *ConstInt = dyn_cast<ConstantInt>(CastInst->getOperand(0))) { 335 // Pretend the constant is directly used by the instruction and ignore 336 // the cast instruction. 337 collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); 338 continue; 339 } 340 } 341 342 // Visit constant expressions that have constant integers. 343 if (auto ConstExpr = dyn_cast<ConstantExpr>(Opnd)) { 344 // Only visit constant cast expressions. 345 if (!ConstExpr->isCast()) 346 continue; 347 348 if (auto ConstInt = dyn_cast<ConstantInt>(ConstExpr->getOperand(0))) { 349 // Pretend the constant is directly used by the instruction and ignore 350 // the constant expression. 351 collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); 352 continue; 353 } 354 } 355 } // end of for all operands 356 } 357 358 /// \brief Collect all integer constants in the function that cannot be folded 359 /// into an instruction itself. 360 void ConstantHoisting::collectConstantCandidates(Function &Fn) { 361 ConstCandMapType ConstCandMap; 362 for (Function::iterator BB : Fn) 363 for (BasicBlock::iterator Inst : *BB) 364 collectConstantCandidates(ConstCandMap, Inst); 365 } 366 367 /// \brief Find the base constant within the given range and rebase all other 368 /// constants with respect to the base constant. 369 void ConstantHoisting::findAndMakeBaseConstant(ConstCandVecType::iterator S, 370 ConstCandVecType::iterator E) { 371 auto MaxCostItr = S; 372 unsigned NumUses = 0; 373 // Use the constant that has the maximum cost as base constant. 374 for (auto ConstCand = S; ConstCand != E; ++ConstCand) { 375 NumUses += ConstCand->Uses.size(); 376 if (ConstCand->CumulativeCost > MaxCostItr->CumulativeCost) 377 MaxCostItr = ConstCand; 378 } 379 380 // Don't hoist constants that have only one use. 381 if (NumUses <= 1) 382 return; 383 384 ConstantInfo ConstInfo; 385 ConstInfo.BaseConstant = MaxCostItr->ConstInt; 386 Type *Ty = ConstInfo.BaseConstant->getType(); 387 388 // Rebase the constants with respect to the base constant. 389 for (auto ConstCand = S; ConstCand != E; ++ConstCand) { 390 APInt Diff = ConstCand->ConstInt->getValue() - 391 ConstInfo.BaseConstant->getValue(); 392 Constant *Offset = Diff == 0 ? nullptr : ConstantInt::get(Ty, Diff); 393 ConstInfo.RebasedConstants.push_back( 394 RebasedConstantInfo(std::move(ConstCand->Uses), Offset)); 395 } 396 ConstantVec.push_back(ConstInfo); 397 } 398 399 /// \brief Finds and combines constant candidates that can be easily 400 /// rematerialized with an add from a common base constant. 401 void ConstantHoisting::findBaseConstants() { 402 // Sort the constants by value and type. This invalidates the mapping! 403 std::sort(ConstCandVec.begin(), ConstCandVec.end(), 404 [](const ConstantCandidate &LHS, const ConstantCandidate &RHS) { 405 if (LHS.ConstInt->getType() != RHS.ConstInt->getType()) 406 return LHS.ConstInt->getType()->getBitWidth() < 407 RHS.ConstInt->getType()->getBitWidth(); 408 return LHS.ConstInt->getValue().ult(RHS.ConstInt->getValue()); 409 }); 410 411 // Simple linear scan through the sorted constant candidate vector for viable 412 // merge candidates. 413 auto MinValItr = ConstCandVec.begin(); 414 for (auto CC = std::next(ConstCandVec.begin()), E = ConstCandVec.end(); 415 CC != E; ++CC) { 416 if (MinValItr->ConstInt->getType() == CC->ConstInt->getType()) { 417 // Check if the constant is in range of an add with immediate. 418 APInt Diff = CC->ConstInt->getValue() - MinValItr->ConstInt->getValue(); 419 if ((Diff.getBitWidth() <= 64) && 420 TTI->isLegalAddImmediate(Diff.getSExtValue())) 421 continue; 422 } 423 // We either have now a different constant type or the constant is not in 424 // range of an add with immediate anymore. 425 findAndMakeBaseConstant(MinValItr, CC); 426 // Start a new base constant search. 427 MinValItr = CC; 428 } 429 // Finalize the last base constant search. 430 findAndMakeBaseConstant(MinValItr, ConstCandVec.end()); 431 } 432 433 /// \brief Updates the operand at Idx in instruction Inst with the result of 434 /// instruction Mat. If the instruction is a PHI node then special 435 /// handling for duplicate values form the same incomming basic block is 436 /// required. 437 /// \return The update will always succeed, but the return value indicated if 438 /// Mat was used for the update or not. 439 static bool updateOperand(Instruction *Inst, unsigned Idx, Instruction *Mat) { 440 if (auto PHI = dyn_cast<PHINode>(Inst)) { 441 // Check if any previous operand of the PHI node has the same incoming basic 442 // block. This is a very odd case that happens when the incoming basic block 443 // has a switch statement. In this case use the same value as the previous 444 // operand(s), otherwise we will fail verification due to different values. 445 // The values are actually the same, but the variable names are different 446 // and the verifier doesn't like that. 447 BasicBlock *IncomingBB = PHI->getIncomingBlock(Idx); 448 for (unsigned i = 0; i < Idx; ++i) { 449 if (PHI->getIncomingBlock(i) == IncomingBB) { 450 Value *IncomingVal = PHI->getIncomingValue(i); 451 Inst->setOperand(Idx, IncomingVal); 452 return false; 453 } 454 } 455 } 456 457 Inst->setOperand(Idx, Mat); 458 return true; 459 } 460 461 /// \brief Emit materialization code for all rebased constants and update their 462 /// users. 463 void ConstantHoisting::emitBaseConstants(Instruction *Base, Constant *Offset, 464 const ConstantUser &ConstUser) { 465 Instruction *Mat = Base; 466 if (Offset) { 467 Instruction *InsertionPt = findMatInsertPt(ConstUser.Inst, 468 ConstUser.OpndIdx); 469 Mat = BinaryOperator::Create(Instruction::Add, Base, Offset, 470 "const_mat", InsertionPt); 471 472 DEBUG(dbgs() << "Materialize constant (" << *Base->getOperand(0) 473 << " + " << *Offset << ") in BB " 474 << Mat->getParent()->getName() << '\n' << *Mat << '\n'); 475 Mat->setDebugLoc(ConstUser.Inst->getDebugLoc()); 476 } 477 Value *Opnd = ConstUser.Inst->getOperand(ConstUser.OpndIdx); 478 479 // Visit constant integer. 480 if (isa<ConstantInt>(Opnd)) { 481 DEBUG(dbgs() << "Update: " << *ConstUser.Inst << '\n'); 482 if (!updateOperand(ConstUser.Inst, ConstUser.OpndIdx, Mat) && Offset) 483 Mat->eraseFromParent(); 484 DEBUG(dbgs() << "To : " << *ConstUser.Inst << '\n'); 485 return; 486 } 487 488 // Visit cast instruction. 489 if (auto CastInst = dyn_cast<Instruction>(Opnd)) { 490 assert(CastInst->isCast() && "Expected an cast instruction!"); 491 // Check if we already have visited this cast instruction before to avoid 492 // unnecessary cloning. 493 Instruction *&ClonedCastInst = ClonedCastMap[CastInst]; 494 if (!ClonedCastInst) { 495 ClonedCastInst = CastInst->clone(); 496 ClonedCastInst->setOperand(0, Mat); 497 ClonedCastInst->insertAfter(CastInst); 498 // Use the same debug location as the original cast instruction. 499 ClonedCastInst->setDebugLoc(CastInst->getDebugLoc()); 500 DEBUG(dbgs() << "Clone instruction: " << *CastInst << '\n' 501 << "To : " << *ClonedCastInst << '\n'); 502 } 503 504 DEBUG(dbgs() << "Update: " << *ConstUser.Inst << '\n'); 505 updateOperand(ConstUser.Inst, ConstUser.OpndIdx, ClonedCastInst); 506 DEBUG(dbgs() << "To : " << *ConstUser.Inst << '\n'); 507 return; 508 } 509 510 // Visit constant expression. 511 if (auto ConstExpr = dyn_cast<ConstantExpr>(Opnd)) { 512 Instruction *ConstExprInst = ConstExpr->getAsInstruction(); 513 ConstExprInst->setOperand(0, Mat); 514 ConstExprInst->insertBefore(findMatInsertPt(ConstUser.Inst, 515 ConstUser.OpndIdx)); 516 517 // Use the same debug location as the instruction we are about to update. 518 ConstExprInst->setDebugLoc(ConstUser.Inst->getDebugLoc()); 519 520 DEBUG(dbgs() << "Create instruction: " << *ConstExprInst << '\n' 521 << "From : " << *ConstExpr << '\n'); 522 DEBUG(dbgs() << "Update: " << *ConstUser.Inst << '\n'); 523 if (!updateOperand(ConstUser.Inst, ConstUser.OpndIdx, ConstExprInst)) { 524 ConstExprInst->eraseFromParent(); 525 if (Offset) 526 Mat->eraseFromParent(); 527 } 528 DEBUG(dbgs() << "To : " << *ConstUser.Inst << '\n'); 529 return; 530 } 531 } 532 533 /// \brief Hoist and hide the base constant behind a bitcast and emit 534 /// materialization code for derived constants. 535 bool ConstantHoisting::emitBaseConstants() { 536 bool MadeChange = false; 537 for (auto const &ConstInfo : ConstantVec) { 538 // Hoist and hide the base constant behind a bitcast. 539 Instruction *IP = findConstantInsertionPoint(ConstInfo); 540 IntegerType *Ty = ConstInfo.BaseConstant->getType(); 541 Instruction *Base = 542 new BitCastInst(ConstInfo.BaseConstant, Ty, "const", IP); 543 DEBUG(dbgs() << "Hoist constant (" << *ConstInfo.BaseConstant << ") to BB " 544 << IP->getParent()->getName() << '\n' << *Base << '\n'); 545 NumConstantsHoisted++; 546 547 // Emit materialization code for all rebased constants. 548 for (auto const &RCI : ConstInfo.RebasedConstants) { 549 NumConstantsRebased++; 550 for (auto const &U : RCI.Uses) 551 emitBaseConstants(Base, RCI.Offset, U); 552 } 553 554 // Use the same debug location as the last user of the constant. 555 assert(!Base->use_empty() && "The use list is empty!?"); 556 assert(isa<Instruction>(Base->user_back()) && 557 "All uses should be instructions."); 558 Base->setDebugLoc(cast<Instruction>(Base->user_back())->getDebugLoc()); 559 560 // Correct for base constant, which we counted above too. 561 NumConstantsRebased--; 562 MadeChange = true; 563 } 564 return MadeChange; 565 } 566 567 /// \brief Check all cast instructions we made a copy of and remove them if they 568 /// have no more users. 569 void ConstantHoisting::deleteDeadCastInst() const { 570 for (auto const &I : ClonedCastMap) 571 if (I.first->use_empty()) 572 I.first->eraseFromParent(); 573 } 574 575 /// \brief Optimize expensive integer constants in the given function. 576 bool ConstantHoisting::optimizeConstants(Function &Fn) { 577 // Collect all constant candidates. 578 collectConstantCandidates(Fn); 579 580 // There are no constant candidates to worry about. 581 if (ConstCandVec.empty()) 582 return false; 583 584 // Combine constants that can be easily materialized with an add from a common 585 // base constant. 586 findBaseConstants(); 587 588 // There are no constants to emit. 589 if (ConstantVec.empty()) 590 return false; 591 592 // Finally hoist the base constant and emit materialization code for dependent 593 // constants. 594 bool MadeChange = emitBaseConstants(); 595 596 // Cleanup dead instructions. 597 deleteDeadCastInst(); 598 599 return MadeChange; 600 } 601