1 //===- CostModel.cpp ------ Cost Model Analysis ---------------------------===// 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 file defines the cost model analysis. It provides a very basic cost 11 // estimation for LLVM-IR. This analysis uses the services of the codegen 12 // to approximate the cost of any IR instruction when lowered to machine 13 // instructions. The cost results are unit-less and the cost number represents 14 // the throughput of the machine assuming that all loads hit the cache, all 15 // branches are predicted, etc. The cost numbers can be added in order to 16 // compare two or more transformation alternatives. 17 // 18 //===----------------------------------------------------------------------===// 19 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/Analysis/Passes.h" 22 #include "llvm/Analysis/TargetTransformInfo.h" 23 #include "llvm/Analysis/VectorUtils.h" 24 #include "llvm/IR/Function.h" 25 #include "llvm/IR/Instructions.h" 26 #include "llvm/IR/IntrinsicInst.h" 27 #include "llvm/IR/PatternMatch.h" 28 #include "llvm/IR/Value.h" 29 #include "llvm/Pass.h" 30 #include "llvm/Support/CommandLine.h" 31 #include "llvm/Support/Debug.h" 32 #include "llvm/Support/raw_ostream.h" 33 using namespace llvm; 34 using namespace PatternMatch; 35 36 #define CM_NAME "cost-model" 37 #define DEBUG_TYPE CM_NAME 38 39 static cl::opt<bool> EnableReduxCost("costmodel-reduxcost", cl::init(false), 40 cl::Hidden, 41 cl::desc("Recognize reduction patterns.")); 42 43 namespace { 44 class CostModelAnalysis : public FunctionPass { 45 46 public: 47 static char ID; // Class identification, replacement for typeinfo 48 CostModelAnalysis() : FunctionPass(ID), F(nullptr), TTI(nullptr) { 49 initializeCostModelAnalysisPass( 50 *PassRegistry::getPassRegistry()); 51 } 52 53 /// Returns the expected cost of the instruction. 54 /// Returns -1 if the cost is unknown. 55 /// Note, this method does not cache the cost calculation and it 56 /// can be expensive in some cases. 57 unsigned getInstructionCost(const Instruction *I) const; 58 59 private: 60 void getAnalysisUsage(AnalysisUsage &AU) const override; 61 bool runOnFunction(Function &F) override; 62 void print(raw_ostream &OS, const Module*) const override; 63 64 /// The function that we analyze. 65 Function *F; 66 /// Target information. 67 const TargetTransformInfo *TTI; 68 }; 69 } // End of anonymous namespace 70 71 // Register this pass. 72 char CostModelAnalysis::ID = 0; 73 static const char cm_name[] = "Cost Model Analysis"; 74 INITIALIZE_PASS_BEGIN(CostModelAnalysis, CM_NAME, cm_name, false, true) 75 INITIALIZE_PASS_END (CostModelAnalysis, CM_NAME, cm_name, false, true) 76 77 FunctionPass *llvm::createCostModelAnalysisPass() { 78 return new CostModelAnalysis(); 79 } 80 81 void 82 CostModelAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { 83 AU.setPreservesAll(); 84 } 85 86 bool 87 CostModelAnalysis::runOnFunction(Function &F) { 88 this->F = &F; 89 auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>(); 90 TTI = TTIWP ? &TTIWP->getTTI(F) : nullptr; 91 92 return false; 93 } 94 95 static bool isReverseVectorMask(ArrayRef<int> Mask) { 96 for (unsigned i = 0, MaskSize = Mask.size(); i < MaskSize; ++i) 97 if (Mask[i] >= 0 && Mask[i] != (int)(MaskSize - 1 - i)) 98 return false; 99 return true; 100 } 101 102 static bool isSingleSourceVectorMask(ArrayRef<int> Mask) { 103 bool Vec0 = false; 104 bool Vec1 = false; 105 for (unsigned i = 0, NumVecElts = Mask.size(); i < NumVecElts; ++i) { 106 if (Mask[i] >= 0) { 107 if ((unsigned)Mask[i] >= NumVecElts) 108 Vec1 = true; 109 else 110 Vec0 = true; 111 } 112 } 113 return !(Vec0 && Vec1); 114 } 115 116 static bool isZeroEltBroadcastVectorMask(ArrayRef<int> Mask) { 117 for (unsigned i = 0; i < Mask.size(); ++i) 118 if (Mask[i] > 0) 119 return false; 120 return true; 121 } 122 123 static bool isAlternateVectorMask(ArrayRef<int> Mask) { 124 bool isAlternate = true; 125 unsigned MaskSize = Mask.size(); 126 127 // Example: shufflevector A, B, <0,5,2,7> 128 for (unsigned i = 0; i < MaskSize && isAlternate; ++i) { 129 if (Mask[i] < 0) 130 continue; 131 isAlternate = Mask[i] == (int)((i & 1) ? MaskSize + i : i); 132 } 133 134 if (isAlternate) 135 return true; 136 137 isAlternate = true; 138 // Example: shufflevector A, B, <4,1,6,3> 139 for (unsigned i = 0; i < MaskSize && isAlternate; ++i) { 140 if (Mask[i] < 0) 141 continue; 142 isAlternate = Mask[i] == (int)((i & 1) ? i : MaskSize + i); 143 } 144 145 return isAlternate; 146 } 147 148 static TargetTransformInfo::OperandValueKind getOperandInfo(Value *V) { 149 TargetTransformInfo::OperandValueKind OpInfo = 150 TargetTransformInfo::OK_AnyValue; 151 152 // Check for a splat of a constant or for a non uniform vector of constants. 153 if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) { 154 OpInfo = TargetTransformInfo::OK_NonUniformConstantValue; 155 if (cast<Constant>(V)->getSplatValue() != nullptr) 156 OpInfo = TargetTransformInfo::OK_UniformConstantValue; 157 } 158 159 // Check for a splat of a uniform value. This is not loop aware, so return 160 // true only for the obviously uniform cases (argument, globalvalue) 161 const Value *Splat = getSplatValue(V); 162 if (Splat && (isa<Argument>(Splat) || isa<GlobalValue>(Splat))) 163 OpInfo = TargetTransformInfo::OK_UniformValue; 164 165 return OpInfo; 166 } 167 168 static bool matchPairwiseShuffleMask(ShuffleVectorInst *SI, bool IsLeft, 169 unsigned Level) { 170 // We don't need a shuffle if we just want to have element 0 in position 0 of 171 // the vector. 172 if (!SI && Level == 0 && IsLeft) 173 return true; 174 else if (!SI) 175 return false; 176 177 SmallVector<int, 32> Mask(SI->getType()->getVectorNumElements(), -1); 178 179 // Build a mask of 0, 2, ... (left) or 1, 3, ... (right) depending on whether 180 // we look at the left or right side. 181 for (unsigned i = 0, e = (1 << Level), val = !IsLeft; i != e; ++i, val += 2) 182 Mask[i] = val; 183 184 SmallVector<int, 16> ActualMask = SI->getShuffleMask(); 185 return Mask == ActualMask; 186 } 187 188 namespace { 189 /// Contains opcode + LHS/RHS parts of the reduction operations. 190 struct ReductionData { 191 explicit ReductionData() = default; 192 ReductionData(unsigned Opcode, Value *LHS, Value *RHS) 193 : Opcode(Opcode), LHS(LHS), RHS(RHS) {} 194 unsigned Opcode = 0; 195 Value *LHS = nullptr; 196 Value *RHS = nullptr; 197 }; 198 } // namespace 199 200 static Optional<ReductionData> getReductionData(Instruction *I) { 201 Value *L, *R; 202 if (m_BinOp(m_Value(L), m_Value(R)).match(I)) 203 return ReductionData(I->getOpcode(), L, R); 204 return llvm::None; 205 } 206 207 static bool matchPairwiseReductionAtLevel(Instruction *I, unsigned Level, 208 unsigned NumLevels) { 209 // Match one level of pairwise operations. 210 // %rdx.shuf.0.0 = shufflevector <4 x float> %rdx, <4 x float> undef, 211 // <4 x i32> <i32 0, i32 2 , i32 undef, i32 undef> 212 // %rdx.shuf.0.1 = shufflevector <4 x float> %rdx, <4 x float> undef, 213 // <4 x i32> <i32 1, i32 3, i32 undef, i32 undef> 214 // %bin.rdx.0 = fadd <4 x float> %rdx.shuf.0.0, %rdx.shuf.0.1 215 if (!I) 216 return false; 217 218 assert(I->getType()->isVectorTy() && "Expecting a vector type"); 219 220 Optional<ReductionData> RD = getReductionData(I); 221 if (!RD) 222 return false; 223 224 ShuffleVectorInst *LS = dyn_cast<ShuffleVectorInst>(RD->LHS); 225 if (!LS && Level) 226 return false; 227 ShuffleVectorInst *RS = dyn_cast<ShuffleVectorInst>(RD->RHS); 228 if (!RS && Level) 229 return false; 230 231 // On level 0 we can omit one shufflevector instruction. 232 if (!Level && !RS && !LS) 233 return false; 234 235 // Shuffle inputs must match. 236 Value *NextLevelOpL = LS ? LS->getOperand(0) : nullptr; 237 Value *NextLevelOpR = RS ? RS->getOperand(0) : nullptr; 238 Value *NextLevelOp = nullptr; 239 if (NextLevelOpR && NextLevelOpL) { 240 // If we have two shuffles their operands must match. 241 if (NextLevelOpL != NextLevelOpR) 242 return false; 243 244 NextLevelOp = NextLevelOpL; 245 } else if (Level == 0 && (NextLevelOpR || NextLevelOpL)) { 246 // On the first level we can omit the shufflevector <0, undef,...>. So the 247 // input to the other shufflevector <1, undef> must match with one of the 248 // inputs to the current binary operation. 249 // Example: 250 // %NextLevelOpL = shufflevector %R, <1, undef ...> 251 // %BinOp = fadd %NextLevelOpL, %R 252 if (NextLevelOpL && NextLevelOpL != RD->RHS) 253 return false; 254 else if (NextLevelOpR && NextLevelOpR != RD->LHS) 255 return false; 256 257 NextLevelOp = NextLevelOpL ? RD->RHS : RD->LHS; 258 } else 259 return false; 260 261 // Check that the next levels binary operation exists and matches with the 262 // current one. 263 if (Level + 1 != NumLevels) { 264 Optional<ReductionData> NextLevelRD = 265 getReductionData(cast<Instruction>(NextLevelOp)); 266 if (!NextLevelRD || RD->Opcode != NextLevelRD->Opcode) 267 return false; 268 } 269 270 // Shuffle mask for pairwise operation must match. 271 if (matchPairwiseShuffleMask(LS, /*IsLeft=*/true, Level)) { 272 if (!matchPairwiseShuffleMask(RS, /*IsLeft=*/false, Level)) 273 return false; 274 } else if (matchPairwiseShuffleMask(RS, /*IsLeft=*/true, Level)) { 275 if (!matchPairwiseShuffleMask(LS, /*IsLeft=*/false, Level)) 276 return false; 277 } else 278 return false; 279 280 if (++Level == NumLevels) 281 return true; 282 283 // Match next level. 284 return matchPairwiseReductionAtLevel(cast<Instruction>(NextLevelOp), Level, 285 NumLevels); 286 } 287 288 static bool matchPairwiseReduction(const ExtractElementInst *ReduxRoot, 289 unsigned &Opcode, Type *&Ty) { 290 if (!EnableReduxCost) 291 return false; 292 293 // Need to extract the first element. 294 ConstantInt *CI = dyn_cast<ConstantInt>(ReduxRoot->getOperand(1)); 295 unsigned Idx = ~0u; 296 if (CI) 297 Idx = CI->getZExtValue(); 298 if (Idx != 0) 299 return false; 300 301 auto *RdxStart = dyn_cast<Instruction>(ReduxRoot->getOperand(0)); 302 if (!RdxStart) 303 return false; 304 Optional<ReductionData> RD = getReductionData(RdxStart); 305 if (!RD) 306 return false; 307 308 Type *VecTy = RdxStart->getType(); 309 unsigned NumVecElems = VecTy->getVectorNumElements(); 310 if (!isPowerOf2_32(NumVecElems)) 311 return false; 312 313 // We look for a sequence of shuffle,shuffle,add triples like the following 314 // that builds a pairwise reduction tree. 315 // 316 // (X0, X1, X2, X3) 317 // (X0 + X1, X2 + X3, undef, undef) 318 // ((X0 + X1) + (X2 + X3), undef, undef, undef) 319 // 320 // %rdx.shuf.0.0 = shufflevector <4 x float> %rdx, <4 x float> undef, 321 // <4 x i32> <i32 0, i32 2 , i32 undef, i32 undef> 322 // %rdx.shuf.0.1 = shufflevector <4 x float> %rdx, <4 x float> undef, 323 // <4 x i32> <i32 1, i32 3, i32 undef, i32 undef> 324 // %bin.rdx.0 = fadd <4 x float> %rdx.shuf.0.0, %rdx.shuf.0.1 325 // %rdx.shuf.1.0 = shufflevector <4 x float> %bin.rdx.0, <4 x float> undef, 326 // <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef> 327 // %rdx.shuf.1.1 = shufflevector <4 x float> %bin.rdx.0, <4 x float> undef, 328 // <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> 329 // %bin.rdx8 = fadd <4 x float> %rdx.shuf.1.0, %rdx.shuf.1.1 330 // %r = extractelement <4 x float> %bin.rdx8, i32 0 331 if (!matchPairwiseReductionAtLevel(RdxStart, 0, Log2_32(NumVecElems))) 332 return false; 333 334 Opcode = RD->Opcode; 335 Ty = VecTy; 336 337 return true; 338 } 339 340 static std::pair<Value *, ShuffleVectorInst *> 341 getShuffleAndOtherOprd(Value *L, Value *R) { 342 ShuffleVectorInst *S = nullptr; 343 344 if ((S = dyn_cast<ShuffleVectorInst>(L))) 345 return std::make_pair(R, S); 346 347 S = dyn_cast<ShuffleVectorInst>(R); 348 return std::make_pair(L, S); 349 } 350 351 static bool matchVectorSplittingReduction(const ExtractElementInst *ReduxRoot, 352 unsigned &Opcode, Type *&Ty) { 353 if (!EnableReduxCost) 354 return false; 355 356 // Need to extract the first element. 357 ConstantInt *CI = dyn_cast<ConstantInt>(ReduxRoot->getOperand(1)); 358 unsigned Idx = ~0u; 359 if (CI) 360 Idx = CI->getZExtValue(); 361 if (Idx != 0) 362 return false; 363 364 auto *RdxStart = dyn_cast<Instruction>(ReduxRoot->getOperand(0)); 365 if (!RdxStart) 366 return false; 367 Optional<ReductionData> RD = getReductionData(RdxStart); 368 if (!RD) 369 return false; 370 371 Type *VecTy = ReduxRoot->getOperand(0)->getType(); 372 unsigned NumVecElems = VecTy->getVectorNumElements(); 373 if (!isPowerOf2_32(NumVecElems)) 374 return false; 375 376 // We look for a sequence of shuffles and adds like the following matching one 377 // fadd, shuffle vector pair at a time. 378 // 379 // %rdx.shuf = shufflevector <4 x float> %rdx, <4 x float> undef, 380 // <4 x i32> <i32 2, i32 3, i32 undef, i32 undef> 381 // %bin.rdx = fadd <4 x float> %rdx, %rdx.shuf 382 // %rdx.shuf7 = shufflevector <4 x float> %bin.rdx, <4 x float> undef, 383 // <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> 384 // %bin.rdx8 = fadd <4 x float> %bin.rdx, %rdx.shuf7 385 // %r = extractelement <4 x float> %bin.rdx8, i32 0 386 387 unsigned MaskStart = 1; 388 Instruction *RdxOp = RdxStart; 389 SmallVector<int, 32> ShuffleMask(NumVecElems, 0); 390 unsigned NumVecElemsRemain = NumVecElems; 391 while (NumVecElemsRemain - 1) { 392 // Check for the right reduction operation. 393 if (!RdxOp) 394 return false; 395 Optional<ReductionData> RDLevel = getReductionData(RdxOp); 396 if (!RDLevel || RDLevel->Opcode != RD->Opcode) 397 return false; 398 399 Value *NextRdxOp; 400 ShuffleVectorInst *Shuffle; 401 std::tie(NextRdxOp, Shuffle) = 402 getShuffleAndOtherOprd(RDLevel->LHS, RDLevel->RHS); 403 404 // Check the current reduction operation and the shuffle use the same value. 405 if (Shuffle == nullptr) 406 return false; 407 if (Shuffle->getOperand(0) != NextRdxOp) 408 return false; 409 410 // Check that shuffle masks matches. 411 for (unsigned j = 0; j != MaskStart; ++j) 412 ShuffleMask[j] = MaskStart + j; 413 // Fill the rest of the mask with -1 for undef. 414 std::fill(&ShuffleMask[MaskStart], ShuffleMask.end(), -1); 415 416 SmallVector<int, 16> Mask = Shuffle->getShuffleMask(); 417 if (ShuffleMask != Mask) 418 return false; 419 420 RdxOp = dyn_cast<Instruction>(NextRdxOp); 421 NumVecElemsRemain /= 2; 422 MaskStart *= 2; 423 } 424 425 Opcode = RD->Opcode; 426 Ty = VecTy; 427 return true; 428 } 429 430 unsigned CostModelAnalysis::getInstructionCost(const Instruction *I) const { 431 if (!TTI) 432 return -1; 433 434 switch (I->getOpcode()) { 435 case Instruction::GetElementPtr: 436 return TTI->getUserCost(I); 437 438 case Instruction::Ret: 439 case Instruction::PHI: 440 case Instruction::Br: { 441 return TTI->getCFInstrCost(I->getOpcode()); 442 } 443 case Instruction::Add: 444 case Instruction::FAdd: 445 case Instruction::Sub: 446 case Instruction::FSub: 447 case Instruction::Mul: 448 case Instruction::FMul: 449 case Instruction::UDiv: 450 case Instruction::SDiv: 451 case Instruction::FDiv: 452 case Instruction::URem: 453 case Instruction::SRem: 454 case Instruction::FRem: 455 case Instruction::Shl: 456 case Instruction::LShr: 457 case Instruction::AShr: 458 case Instruction::And: 459 case Instruction::Or: 460 case Instruction::Xor: { 461 TargetTransformInfo::OperandValueKind Op1VK = 462 getOperandInfo(I->getOperand(0)); 463 TargetTransformInfo::OperandValueKind Op2VK = 464 getOperandInfo(I->getOperand(1)); 465 SmallVector<const Value*, 2> Operands(I->operand_values()); 466 return TTI->getArithmeticInstrCost(I->getOpcode(), I->getType(), Op1VK, 467 Op2VK, TargetTransformInfo::OP_None, 468 TargetTransformInfo::OP_None, 469 Operands); 470 } 471 case Instruction::Select: { 472 const SelectInst *SI = cast<SelectInst>(I); 473 Type *CondTy = SI->getCondition()->getType(); 474 return TTI->getCmpSelInstrCost(I->getOpcode(), I->getType(), CondTy, I); 475 } 476 case Instruction::ICmp: 477 case Instruction::FCmp: { 478 Type *ValTy = I->getOperand(0)->getType(); 479 return TTI->getCmpSelInstrCost(I->getOpcode(), ValTy, I->getType(), I); 480 } 481 case Instruction::Store: { 482 const StoreInst *SI = cast<StoreInst>(I); 483 Type *ValTy = SI->getValueOperand()->getType(); 484 return TTI->getMemoryOpCost(I->getOpcode(), ValTy, 485 SI->getAlignment(), 486 SI->getPointerAddressSpace(), I); 487 } 488 case Instruction::Load: { 489 const LoadInst *LI = cast<LoadInst>(I); 490 return TTI->getMemoryOpCost(I->getOpcode(), I->getType(), 491 LI->getAlignment(), 492 LI->getPointerAddressSpace(), I); 493 } 494 case Instruction::ZExt: 495 case Instruction::SExt: 496 case Instruction::FPToUI: 497 case Instruction::FPToSI: 498 case Instruction::FPExt: 499 case Instruction::PtrToInt: 500 case Instruction::IntToPtr: 501 case Instruction::SIToFP: 502 case Instruction::UIToFP: 503 case Instruction::Trunc: 504 case Instruction::FPTrunc: 505 case Instruction::BitCast: 506 case Instruction::AddrSpaceCast: { 507 Type *SrcTy = I->getOperand(0)->getType(); 508 return TTI->getCastInstrCost(I->getOpcode(), I->getType(), SrcTy, I); 509 } 510 case Instruction::ExtractElement: { 511 const ExtractElementInst * EEI = cast<ExtractElementInst>(I); 512 ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1)); 513 unsigned Idx = -1; 514 if (CI) 515 Idx = CI->getZExtValue(); 516 517 // Try to match a reduction sequence (series of shufflevector and vector 518 // adds followed by a extractelement). 519 unsigned ReduxOpCode; 520 Type *ReduxType; 521 522 if (matchVectorSplittingReduction(EEI, ReduxOpCode, ReduxType)) { 523 return TTI->getArithmeticReductionCost(ReduxOpCode, ReduxType, 524 /*IsPairwiseForm=*/false); 525 } 526 if (matchPairwiseReduction(EEI, ReduxOpCode, ReduxType)) { 527 return TTI->getArithmeticReductionCost(ReduxOpCode, ReduxType, 528 /*IsPairwiseForm=*/true); 529 } 530 531 return TTI->getVectorInstrCost(I->getOpcode(), 532 EEI->getOperand(0)->getType(), Idx); 533 } 534 case Instruction::InsertElement: { 535 const InsertElementInst * IE = cast<InsertElementInst>(I); 536 ConstantInt *CI = dyn_cast<ConstantInt>(IE->getOperand(2)); 537 unsigned Idx = -1; 538 if (CI) 539 Idx = CI->getZExtValue(); 540 return TTI->getVectorInstrCost(I->getOpcode(), 541 IE->getType(), Idx); 542 } 543 case Instruction::ShuffleVector: { 544 const ShuffleVectorInst *Shuffle = cast<ShuffleVectorInst>(I); 545 Type *VecTypOp0 = Shuffle->getOperand(0)->getType(); 546 unsigned NumVecElems = VecTypOp0->getVectorNumElements(); 547 SmallVector<int, 16> Mask = Shuffle->getShuffleMask(); 548 549 if (NumVecElems == Mask.size()) { 550 if (isReverseVectorMask(Mask)) 551 return TTI->getShuffleCost(TargetTransformInfo::SK_Reverse, VecTypOp0, 552 0, nullptr); 553 if (isAlternateVectorMask(Mask)) 554 return TTI->getShuffleCost(TargetTransformInfo::SK_Alternate, 555 VecTypOp0, 0, nullptr); 556 557 if (isZeroEltBroadcastVectorMask(Mask)) 558 return TTI->getShuffleCost(TargetTransformInfo::SK_Broadcast, 559 VecTypOp0, 0, nullptr); 560 561 if (isSingleSourceVectorMask(Mask)) 562 return TTI->getShuffleCost(TargetTransformInfo::SK_PermuteSingleSrc, 563 VecTypOp0, 0, nullptr); 564 565 return TTI->getShuffleCost(TargetTransformInfo::SK_PermuteTwoSrc, 566 VecTypOp0, 0, nullptr); 567 } 568 569 return -1; 570 } 571 case Instruction::Call: 572 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) { 573 SmallVector<Value *, 4> Args(II->arg_operands()); 574 575 FastMathFlags FMF; 576 if (auto *FPMO = dyn_cast<FPMathOperator>(II)) 577 FMF = FPMO->getFastMathFlags(); 578 579 return TTI->getIntrinsicInstrCost(II->getIntrinsicID(), II->getType(), 580 Args, FMF); 581 } 582 return -1; 583 default: 584 // We don't have any information on this instruction. 585 return -1; 586 } 587 } 588 589 void CostModelAnalysis::print(raw_ostream &OS, const Module*) const { 590 if (!F) 591 return; 592 593 for (BasicBlock &B : *F) { 594 for (Instruction &Inst : B) { 595 unsigned Cost = getInstructionCost(&Inst); 596 if (Cost != (unsigned)-1) 597 OS << "Cost Model: Found an estimated cost of " << Cost; 598 else 599 OS << "Cost Model: Unknown cost"; 600 601 OS << " for instruction: " << Inst << "\n"; 602 } 603 } 604 } 605