16059Samurai//===- CostModel.cpp ------ Cost Model Analysis ---------------------------===//
26059Samurai//
36059Samurai//                     The LLVM Compiler Infrastructure
46059Samurai//
56059Samurai// This file is distributed under the University of Illinois Open Source
66059Samurai// License. See LICENSE.TXT for details.
76059Samurai//
86059Samurai//===----------------------------------------------------------------------===//
96059Samurai//
106059Samurai// This file defines the cost model analysis. It provides a very basic cost
116059Samurai// estimation for LLVM-IR. This analysis uses the services of the codegen
126059Samurai// to approximate the cost of any IR instruction when lowered to machine
136059Samurai// instructions. The cost results are unit-less and the cost number represents
146059Samurai// the throughput of the machine assuming that all loads hit the cache, all
156059Samurai// branches are predicted, etc. The cost numbers can be added in order to
166059Samurai// compare two or more transformation alternatives.
176059Samurai//
186059Samurai//===----------------------------------------------------------------------===//
198857Srgrimes
2050479Speter#define CM_NAME "cost-model"
218857Srgrimes#define DEBUG_TYPE CM_NAME
226059Samurai#include "llvm/ADT/STLExtras.h"
2343313Sbrian#include "llvm/Analysis/Passes.h"
2430715Sbrian#include "llvm/Analysis/TargetTransformInfo.h"
2526031Sbrian#include "llvm/IR/Function.h"
2630715Sbrian#include "llvm/IR/Instructions.h"
2726031Sbrian#include "llvm/IR/IntrinsicInst.h"
2830715Sbrian#include "llvm/IR/Value.h"
2926031Sbrian#include "llvm/Pass.h"
3030715Sbrian#include "llvm/Support/CommandLine.h"
3136285Sbrian#include "llvm/Support/Debug.h"
3230715Sbrian#include "llvm/Support/raw_ostream.h"
3338628Sbrianusing namespace llvm;
3430715Sbrian
3526516Sbrianstatic cl::opt<bool> EnableReduxCost("costmodel-reduxcost", cl::init(false),
3630715Sbrian                                     cl::Hidden,
3730715Sbrian                                     cl::desc("Recognize reduction patterns."));
3830715Sbrian
3930715Sbriannamespace {
4030715Sbrian  class CostModelAnalysis : public FunctionPass {
4130715Sbrian
4230715Sbrian  public:
4330715Sbrian    static char ID; // Class identification, replacement for typeinfo
4450059Sbrian    CostModelAnalysis() : FunctionPass(ID), F(0), TTI(0) {
4558037Sbrian      initializeCostModelAnalysisPass(
4658037Sbrian        *PassRegistry::getPassRegistry());
4758037Sbrian    }
4846086Sbrian
4939395Sbrian    /// Returns the expected cost of the instruction.
5039395Sbrian    /// Returns -1 if the cost is unknown.
5158037Sbrian    /// Note, this method does not cache the cost calculation and it
5246686Sbrian    /// can be expensive in some cases.
5337009Sbrian    unsigned getInstructionCost(const Instruction *I) const;
5431343Sbrian
5530715Sbrian  private:
5630715Sbrian    virtual void getAnalysisUsage(AnalysisUsage &AU) const;
5730715Sbrian    virtual bool runOnFunction(Function &F);
586059Samurai    virtual void print(raw_ostream &OS, const Module*) const;
5931690Sbrian
6036285Sbrian    /// The function that we analyze.
6136285Sbrian    Function *F;
6238557Sbrian    /// Target information.
6338557Sbrian    const TargetTransformInfo *TTI;
6463484Sbrian  };
656059Samurai}  // End of anonymous namespace
6650059Sbrian
6751075Sbrian// Register this pass.
6831343Sbrianchar CostModelAnalysis::ID = 0;
6925630Sbrianstatic const char cm_name[] = "Cost Model Analysis";
7036285SbrianINITIALIZE_PASS_BEGIN(CostModelAnalysis, CM_NAME, cm_name, false, true)
7136285SbrianINITIALIZE_PASS_END  (CostModelAnalysis, CM_NAME, cm_name, false, true)
7230715Sbrian
7330715SbrianFunctionPass *llvm::createCostModelAnalysisPass() {
7430715Sbrian  return new CostModelAnalysis();
7531080Sbrian}
7636285Sbrian
7736285Sbrianvoid
7836285SbrianCostModelAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
7936285Sbrian  AU.setPreservesAll();
8043313Sbrian}
8143313Sbrian
8243313Sbrianbool
8336285SbrianCostModelAnalysis::runOnFunction(Function &F) {
8436285Sbrian this->F = &F;
8536285Sbrian TTI = getAnalysisIfAvailable<TargetTransformInfo>();
8636285Sbrian
8736285Sbrian return false;
8838174Sbrian}
8936285Sbrian
9040561Sbrianstatic bool isReverseVectorMask(SmallVectorImpl<int> &Mask) {
9153298Sbrian  for (unsigned i = 0, MaskSize = Mask.size(); i < MaskSize; ++i)
926059Samurai    if (Mask[i] > 0 && Mask[i] != (int)(MaskSize - 1 - i))
9336285Sbrian      return false;
9436285Sbrian  return true;
9536285Sbrian}
9636285Sbrian
9736285Sbrianstatic TargetTransformInfo::OperandValueKind getOperandInfo(Value *V) {
9836285Sbrian  TargetTransformInfo::OperandValueKind OpInfo =
9936285Sbrian    TargetTransformInfo::OK_AnyValue;
10036285Sbrian
10136285Sbrian  // Check for a splat of a constant.
10236285Sbrian  ConstantDataVector *CDV = 0;
10336285Sbrian  if ((CDV = dyn_cast<ConstantDataVector>(V)))
10436285Sbrian    if (CDV->getSplatValue() != NULL)
10536285Sbrian      OpInfo = TargetTransformInfo::OK_UniformConstantValue;
10636285Sbrian  ConstantVector *CV = 0;
10736285Sbrian  if ((CV = dyn_cast<ConstantVector>(V)))
10836285Sbrian    if (CV->getSplatValue() != NULL)
10936285Sbrian      OpInfo = TargetTransformInfo::OK_UniformConstantValue;
11036285Sbrian
11136285Sbrian  return OpInfo;
11236285Sbrian}
11336285Sbrian
11436285Sbrianstatic bool matchMask(SmallVectorImpl<int> &M1, SmallVectorImpl<int> &M2) {
11536285Sbrian  if (M1.size() != M2.size())
11636285Sbrian    return false;
11736285Sbrian
11838174Sbrian  for (unsigned i = 0, e = M1.size(); i != e; ++i)
11938174Sbrian    if (M1[i] != M2[i])
12038544Sbrian      return false;
12140665Sbrian
12240665Sbrian  return true;
12343313Sbrian}
12444073Sbrian
12546686Sbrianstatic bool matchPairwiseShuffleMask(ShuffleVectorInst *SI, bool IsLeft,
12646686Sbrian                                     unsigned Level) {
12750867Sbrian  // We don't need a shuffle if we just want to have element 0 in position 0 of
12852488Sbrian  // the vector.
12961534Sbrian  if (!SI && Level == 0 && IsLeft)
1306059Samurai    return true;
13136285Sbrian  else if (!SI)
13236285Sbrian    return false;
13336285Sbrian
13436285Sbrian  SmallVector<int, 32> Mask(SI->getType()->getVectorNumElements(), -1);
13536285Sbrian
13636285Sbrian  // Build a mask of 0, 2, ... (left) or 1, 3, ... (right) depending on whether
13744106Sbrian  // we look at the left or right side.
13844106Sbrian  for (unsigned i = 0, e = (1 << Level), val = !IsLeft; i != e; ++i, val += 2)
13944106Sbrian    Mask[i] = val;
14044106Sbrian
14147858Sbrian  SmallVector<int, 16> ActualMask = SI->getShuffleMask();
14247858Sbrian  if (!matchMask(Mask, ActualMask))
14347858Sbrian    return false;
14447858Sbrian
14547858Sbrian  return true;
14647858Sbrian}
14747858Sbrian
14847858Sbrianstatic bool matchPairwiseReductionAtLevel(const BinaryOperator *BinOp,
14947858Sbrian                                          unsigned Level, unsigned NumLevels) {
15036285Sbrian  // Match one level of pairwise operations.
15164670Sbrian  // %rdx.shuf.0.0 = shufflevector <4 x float> %rdx, <4 x float> undef,
15236285Sbrian  //       <4 x i32> <i32 0, i32 2 , i32 undef, i32 undef>
15336285Sbrian  // %rdx.shuf.0.1 = shufflevector <4 x float> %rdx, <4 x float> undef,
15436285Sbrian  //       <4 x i32> <i32 1, i32 3, i32 undef, i32 undef>
15536285Sbrian  // %bin.rdx.0 = fadd <4 x float> %rdx.shuf.0.0, %rdx.shuf.0.1
15636285Sbrian  if (BinOp == 0)
15736285Sbrian    return false;
15836285Sbrian
15936285Sbrian  assert(BinOp->getType()->isVectorTy() && "Expecting a vector type");
16036285Sbrian
16136285Sbrian  unsigned Opcode = BinOp->getOpcode();
16236285Sbrian  Value *L = BinOp->getOperand(0);
16336285Sbrian  Value *R = BinOp->getOperand(1);
16436934Sbrian
16540561Sbrian  ShuffleVectorInst *LS = dyn_cast<ShuffleVectorInst>(L);
16640561Sbrian  if (!LS && Level)
16740561Sbrian    return false;
16840561Sbrian  ShuffleVectorInst *RS = dyn_cast<ShuffleVectorInst>(R);
16940679Sbrian  if (!RS && Level)
17050059Sbrian    return false;
17158867Sbrian
17258867Sbrian  // On level 0 we can omit one shufflevector instruction.
17331343Sbrian  if (!Level && !RS && !LS)
1746059Samurai    return false;
17536285Sbrian
17636285Sbrian  // Shuffle inputs must match.
17736285Sbrian  Value *NextLevelOpL = LS ? LS->getOperand(0) : 0;
17836285Sbrian  Value *NextLevelOpR = RS ? RS->getOperand(0) : 0;
17936285Sbrian  Value *NextLevelOp = 0;
18036285Sbrian  if (NextLevelOpR && NextLevelOpL) {
18136285Sbrian    // If we have two shuffles their operands must match.
18236285Sbrian    if (NextLevelOpL != NextLevelOpR)
18336285Sbrian      return false;
18436285Sbrian
18536285Sbrian    NextLevelOp = NextLevelOpL;
1866059Samurai  } else if (Level == 0 && (NextLevelOpR || NextLevelOpL)) {
18731343Sbrian    // On the first level we can omit the shufflevector <0, undef,...>. So the
1886059Samurai    // input to the other shufflevector <1, undef> must match with one of the
18928679Sbrian    // inputs to the current binary operation.
19036285Sbrian    // Example:
19136285Sbrian    //  %NextLevelOpL = shufflevector %R, <1, undef ...>
1926059Samurai    //  %BinOp        = fadd          %NextLevelOpL, %R
19336285Sbrian    if (NextLevelOpL && NextLevelOpL != R)
19436285Sbrian      return false;
19526516Sbrian    else if (NextLevelOpR && NextLevelOpR != L)
19636285Sbrian      return false;
19726516Sbrian
19836285Sbrian    NextLevelOp = NextLevelOpL ? R : L;
19936285Sbrian  } else
20036285Sbrian    return false;
20136285Sbrian
20236285Sbrian  // Check that the next levels binary operation exists and matches with the
20336285Sbrian  // current one.
20428679Sbrian  BinaryOperator *NextLevelBinOp = 0;
2056059Samurai  if (Level + 1 != NumLevels) {
20626516Sbrian    if (!(NextLevelBinOp = dyn_cast<BinaryOperator>(NextLevelOp)))
2076059Samurai      return false;
20836285Sbrian    else if (NextLevelBinOp->getOpcode() != Opcode)
20931372Sbrian      return false;
21036285Sbrian  }
21136285Sbrian
21236285Sbrian  // Shuffle mask for pairwise operation must match.
21331372Sbrian  if (matchPairwiseShuffleMask(LS, true, Level)) {
21431372Sbrian    if (!matchPairwiseShuffleMask(RS, false, Level))
21531372Sbrian      return false;
21631372Sbrian  } else if (matchPairwiseShuffleMask(RS, true, Level)) {
21731372Sbrian    if (!matchPairwiseShuffleMask(LS, false, Level))
21831372Sbrian      return false;
2196059Samurai  } else
22036285Sbrian    return false;
22136285Sbrian
22236285Sbrian  if (++Level == NumLevels)
22336285Sbrian    return true;
22436285Sbrian
22536285Sbrian  // Match next level.
22640482Sbrian  return matchPairwiseReductionAtLevel(NextLevelBinOp, Level, NumLevels);
22740482Sbrian}
22840482Sbrian
22936285Sbrianstatic bool matchPairwiseReduction(const ExtractElementInst *ReduxRoot,
23031372Sbrian                                   unsigned &Opcode, Type *&Ty) {
23136285Sbrian  if (!EnableReduxCost)
2326059Samurai    return false;
23331372Sbrian
23436285Sbrian  // Need to extract the first element.
23526516Sbrian  ConstantInt *CI = dyn_cast<ConstantInt>(ReduxRoot->getOperand(1));
23626516Sbrian  unsigned Idx = ~0u;
2376059Samurai  if (CI)
2386059Samurai    Idx = CI->getZExtValue();
23936285Sbrian  if (Idx != 0)
24063484Sbrian    return false;
24163484Sbrian
24263484Sbrian  BinaryOperator *RdxStart = dyn_cast<BinaryOperator>(ReduxRoot->getOperand(0));
24363484Sbrian  if (!RdxStart)
24463484Sbrian    return false;
24563484Sbrian
24663484Sbrian  Type *VecTy = ReduxRoot->getOperand(0)->getType();
24763484Sbrian  unsigned NumVecElems = VecTy->getVectorNumElements();
24863484Sbrian  if (!isPowerOf2_32(NumVecElems))
24963484Sbrian    return false;
25063484Sbrian
25163484Sbrian  // We look for a sequence of shuffle,shuffle,add triples like the following
25263484Sbrian  // that builds a pairwise reduction tree.
25363484Sbrian  //
25463484Sbrian  //  (X0, X1, X2, X3)
25563484Sbrian  //   (X0 + X1, X2 + X3, undef, undef)
25663484Sbrian  //    ((X0 + X1) + (X2 + X3), undef, undef, undef)
25763484Sbrian  //
25863484Sbrian  // %rdx.shuf.0.0 = shufflevector <4 x float> %rdx, <4 x float> undef,
25963484Sbrian  //       <4 x i32> <i32 0, i32 2 , i32 undef, i32 undef>
26063484Sbrian  // %rdx.shuf.0.1 = shufflevector <4 x float> %rdx, <4 x float> undef,
26163484Sbrian  //       <4 x i32> <i32 1, i32 3, i32 undef, i32 undef>
26263484Sbrian  // %bin.rdx.0 = fadd <4 x float> %rdx.shuf.0.0, %rdx.shuf.0.1
26363484Sbrian  // %rdx.shuf.1.0 = shufflevector <4 x float> %bin.rdx.0, <4 x float> undef,
26463484Sbrian  //       <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
26536285Sbrian  // %rdx.shuf.1.1 = shufflevector <4 x float> %bin.rdx.0, <4 x float> undef,
2666059Samurai  //       <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
26736285Sbrian  // %bin.rdx8 = fadd <4 x float> %rdx.shuf.1.0, %rdx.shuf.1.1
26836285Sbrian  // %r = extractelement <4 x float> %bin.rdx8, i32 0
26936285Sbrian  if (!matchPairwiseReductionAtLevel(RdxStart, 0,  Log2_32(NumVecElems)))
2706059Samurai    return false;
27136285Sbrian
27236285Sbrian  Opcode = RdxStart->getOpcode();
27336285Sbrian  Ty = VecTy;
27436285Sbrian
27536285Sbrian  return true;
27636285Sbrian}
27736285Sbrian
27836285Sbrianstatic std::pair<Value *, ShuffleVectorInst *>
2796059SamuraigetShuffleAndOtherOprd(BinaryOperator *B) {
28036285Sbrian
28136285Sbrian  Value *L = B->getOperand(0);
2826059Samurai  Value *R = B->getOperand(1);
2836059Samurai  ShuffleVectorInst *S = 0;
2846059Samurai
28536285Sbrian  if ((S = dyn_cast<ShuffleVectorInst>(L)))
2866059Samurai    return std::make_pair(R, S);
28736285Sbrian
28836285Sbrian  S = dyn_cast<ShuffleVectorInst>(R);
28911336Samurai  return std::make_pair(L, S);
29036285Sbrian}
29136285Sbrian
29236285Sbrianstatic bool matchVectorSplittingReduction(const ExtractElementInst *ReduxRoot,
2936059Samurai                                          unsigned &Opcode, Type *&Ty) {
29426516Sbrian  if (!EnableReduxCost)
29536285Sbrian    return false;
29636285Sbrian
29736285Sbrian  // Need to extract the first element.
29832711Sbrian  ConstantInt *CI = dyn_cast<ConstantInt>(ReduxRoot->getOperand(1));
29936285Sbrian  unsigned Idx = ~0u;
30036285Sbrian  if (CI)
30136285Sbrian    Idx = CI->getZExtValue();
30236285Sbrian  if (Idx != 0)
30336285Sbrian    return false;
30431121Sbrian
30536285Sbrian  BinaryOperator *RdxStart = dyn_cast<BinaryOperator>(ReduxRoot->getOperand(0));
30636285Sbrian  if (!RdxStart)
30736285Sbrian    return false;
30836285Sbrian  unsigned RdxOpcode = RdxStart->getOpcode();
30936285Sbrian
31036285Sbrian  Type *VecTy = ReduxRoot->getOperand(0)->getType();
31136285Sbrian  unsigned NumVecElems = VecTy->getVectorNumElements();
31236285Sbrian  if (!isPowerOf2_32(NumVecElems))
31336285Sbrian    return false;
31436285Sbrian
31536285Sbrian  // We look for a sequence of shuffles and adds like the following matching one
31640797Sbrian  // fadd, shuffle vector pair at a time.
31740797Sbrian  //
31836285Sbrian  // %rdx.shuf = shufflevector <4 x float> %rdx, <4 x float> undef,
31940797Sbrian  //                           <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
32036285Sbrian  // %bin.rdx = fadd <4 x float> %rdx, %rdx.shuf
32140797Sbrian  // %rdx.shuf7 = shufflevector <4 x float> %bin.rdx, <4 x float> undef,
32240797Sbrian  //                          <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
32340797Sbrian  // %bin.rdx8 = fadd <4 x float> %bin.rdx, %rdx.shuf7
32440797Sbrian  // %r = extractelement <4 x float> %bin.rdx8, i32 0
32540797Sbrian
32640797Sbrian  unsigned MaskStart = 1;
32740797Sbrian  Value *RdxOp = RdxStart;
32840797Sbrian  SmallVector<int, 32> ShuffleMask(NumVecElems, 0);
32940797Sbrian  unsigned NumVecElemsRemain = NumVecElems;
33040797Sbrian  while (NumVecElemsRemain - 1) {
33140797Sbrian    // Check for the right reduction operation.
33240797Sbrian    BinaryOperator *BinOp;
33340797Sbrian    if (!(BinOp = dyn_cast<BinaryOperator>(RdxOp)))
33440797Sbrian      return false;
33536285Sbrian    if (BinOp->getOpcode() != RdxOpcode)
33636285Sbrian      return false;
33740797Sbrian
33840797Sbrian    Value *NextRdxOp;
33940797Sbrian    ShuffleVectorInst *Shuffle;
34036285Sbrian    tie(NextRdxOp, Shuffle) = getShuffleAndOtherOprd(BinOp);
34140797Sbrian
34226516Sbrian    // Check the current reduction operation and the shuffle use the same value.
3436059Samurai    if (Shuffle == 0)
3446059Samurai      return false;
34536285Sbrian    if (Shuffle->getOperand(0) != NextRdxOp)
34636285Sbrian      return false;
34736285Sbrian
34836285Sbrian    // Check that shuffle masks matches.
34936285Sbrian    for (unsigned j = 0; j != MaskStart; ++j)
35036285Sbrian      ShuffleMask[j] = MaskStart + j;
35136285Sbrian    // Fill the rest of the mask with -1 for undef.
35210528Samurai    std::fill(&ShuffleMask[MaskStart], ShuffleMask.end(), -1);
35336285Sbrian
35428536Sbrian    SmallVector<int, 16> Mask = Shuffle->getShuffleMask();
35536285Sbrian    if (!matchMask(ShuffleMask, Mask))
35636285Sbrian      return false;
35736465Sbrian
35836465Sbrian    RdxOp = NextRdxOp;
35936928Sbrian    NumVecElemsRemain /= 2;
36036285Sbrian    MaskStart *= 2;
36136285Sbrian  }
36236285Sbrian
36334536Sbrian  Opcode = RdxOpcode;
36436285Sbrian  Ty = VecTy;
36536285Sbrian  return true;
36636285Sbrian}
36736285Sbrian
36837993Sbrianunsigned CostModelAnalysis::getInstructionCost(const Instruction *I) const {
36936285Sbrian  if (!TTI)
37036285Sbrian    return -1;
37128536Sbrian
37228536Sbrian  switch (I->getOpcode()) {
37338628Sbrian  case Instruction::GetElementPtr:{
37438628Sbrian    Type *ValTy = I->getOperand(0)->getType()->getPointerElementType();
37538628Sbrian    return TTI->getAddressComputationCost(ValTy);
37638628Sbrian  }
37738628Sbrian
37838628Sbrian  case Instruction::Ret:
37938628Sbrian  case Instruction::PHI:
38038628Sbrian  case Instruction::Br: {
38138628Sbrian    return TTI->getCFInstrCost(I->getOpcode());
38238628Sbrian  }
38338628Sbrian  case Instruction::Add:
38438628Sbrian  case Instruction::FAdd:
38538628Sbrian  case Instruction::Sub:
38647865Sbrian  case Instruction::FSub:
38747865Sbrian  case Instruction::Mul:
38847865Sbrian  case Instruction::FMul:
38947865Sbrian  case Instruction::UDiv:
39047865Sbrian  case Instruction::SDiv:
39138628Sbrian  case Instruction::FDiv:
39238628Sbrian  case Instruction::URem:
39338628Sbrian  case Instruction::SRem:
39438628Sbrian  case Instruction::FRem:
39538628Sbrian  case Instruction::Shl:
39638628Sbrian  case Instruction::LShr:
39738628Sbrian  case Instruction::AShr:
39838628Sbrian  case Instruction::And:
39938628Sbrian  case Instruction::Or:
40038628Sbrian  case Instruction::Xor: {
40138628Sbrian    TargetTransformInfo::OperandValueKind Op1VK =
40238628Sbrian      getOperandInfo(I->getOperand(0));
40338628Sbrian    TargetTransformInfo::OperandValueKind Op2VK =
40438628Sbrian      getOperandInfo(I->getOperand(1));
40538628Sbrian    return TTI->getArithmeticInstrCost(I->getOpcode(), I->getType(), Op1VK,
40638628Sbrian                                       Op2VK);
40738628Sbrian  }
40838628Sbrian  case Instruction::Select: {
40938628Sbrian    const SelectInst *SI = cast<SelectInst>(I);
41038628Sbrian    Type *CondTy = SI->getCondition()->getType();
41138628Sbrian    return TTI->getCmpSelInstrCost(I->getOpcode(), I->getType(), CondTy);
41238628Sbrian  }
41338628Sbrian  case Instruction::ICmp:
41438628Sbrian  case Instruction::FCmp: {
41538628Sbrian    Type *ValTy = I->getOperand(0)->getType();
41638628Sbrian    return TTI->getCmpSelInstrCost(I->getOpcode(), ValTy);
41738628Sbrian  }
41838628Sbrian  case Instruction::Store: {
41938628Sbrian    const StoreInst *SI = cast<StoreInst>(I);
42038628Sbrian    Type *ValTy = SI->getValueOperand()->getType();
42138628Sbrian    return TTI->getMemoryOpCost(I->getOpcode(), ValTy,
42238628Sbrian                                 SI->getAlignment(),
42338628Sbrian                                 SI->getPointerAddressSpace());
42438628Sbrian  }
42538628Sbrian  case Instruction::Load: {
42638628Sbrian    const LoadInst *LI = cast<LoadInst>(I);
42738628Sbrian    return TTI->getMemoryOpCost(I->getOpcode(), I->getType(),
42843888Sbrian                                 LI->getAlignment(),
42943888Sbrian                                 LI->getPointerAddressSpace());
43047849Sbrian  }
43138628Sbrian  case Instruction::ZExt:
43238628Sbrian  case Instruction::SExt:
43347849Sbrian  case Instruction::FPToUI:
43438628Sbrian  case Instruction::FPToSI:
43541755Sbrian  case Instruction::FPExt:
43641755Sbrian  case Instruction::PtrToInt:
43741755Sbrian  case Instruction::IntToPtr:
43841755Sbrian  case Instruction::SIToFP:
43941755Sbrian  case Instruction::UIToFP:
44041755Sbrian  case Instruction::Trunc:
44147849Sbrian  case Instruction::FPTrunc:
44241755Sbrian  case Instruction::BitCast: {
44338629Sbrian    Type *SrcTy = I->getOperand(0)->getType();
44438629Sbrian    return TTI->getCastInstrCost(I->getOpcode(), I->getType(), SrcTy);
44538628Sbrian  }
44638629Sbrian  case Instruction::ExtractElement: {
44740561Sbrian    const ExtractElementInst * EEI = cast<ExtractElementInst>(I);
44838628Sbrian    ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1));
44938629Sbrian    unsigned Idx = -1;
45038629Sbrian    if (CI)
45138629Sbrian      Idx = CI->getZExtValue();
45238629Sbrian
45338629Sbrian    // Try to match a reduction sequence (series of shufflevector and vector
45438629Sbrian    // adds followed by a extractelement).
45538629Sbrian    unsigned ReduxOpCode;
45638629Sbrian    Type *ReduxType;
45738629Sbrian
45847849Sbrian    if (matchVectorSplittingReduction(EEI, ReduxOpCode, ReduxType))
45938629Sbrian      return TTI->getReductionCost(ReduxOpCode, ReduxType, false);
46058044Sbrian    else if (matchPairwiseReduction(EEI, ReduxOpCode, ReduxType))
46158044Sbrian      return TTI->getReductionCost(ReduxOpCode, ReduxType, true);
46258044Sbrian
46358044Sbrian    return TTI->getVectorInstrCost(I->getOpcode(),
46463484Sbrian                                   EEI->getOperand(0)->getType(), Idx);
46563484Sbrian  }
46638628Sbrian  case Instruction::InsertElement: {
46738628Sbrian    const InsertElementInst * IE = cast<InsertElementInst>(I);
46838628Sbrian    ConstantInt *CI = dyn_cast<ConstantInt>(IE->getOperand(2));
46938628Sbrian    unsigned Idx = -1;
47028536Sbrian    if (CI)
47131343Sbrian      Idx = CI->getZExtValue();
47210528Samurai    return TTI->getVectorInstrCost(I->getOpcode(),
47310528Samurai                                   IE->getType(), Idx);
47447849Sbrian  }
47520813Sjkh  case Instruction::ShuffleVector: {
47618856Ssos    const ShuffleVectorInst *Shuffle = cast<ShuffleVectorInst>(I);
47726911Sbrian    Type *VecTypOp0 = Shuffle->getOperand(0)->getType();
47836285Sbrian    unsigned NumVecElems = VecTypOp0->getVectorNumElements();
47936285Sbrian    SmallVector<int, 16> Mask = Shuffle->getShuffleMask();
48026516Sbrian
48110528Samurai    if (NumVecElems == Mask.size() && isReverseVectorMask(Mask))
48226911Sbrian      return TTI->getShuffleCost(TargetTransformInfo::SK_Reverse, VecTypOp0, 0,
48328679Sbrian                                 0);
48436285Sbrian    return -1;
48536285Sbrian  }
48636285Sbrian  case Instruction::Call:
48736285Sbrian    if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
48828381Sbrian      SmallVector<Type*, 4> Tys;
48936285Sbrian      for (unsigned J = 0, JE = II->getNumArgOperands(); J != JE; ++J)
49036285Sbrian        Tys.push_back(II->getArgOperand(J)->getType());
49136285Sbrian
49236285Sbrian      return TTI->getIntrinsicInstrCost(II->getIntrinsicID(), II->getType(),
49328381Sbrian                                        Tys);
49436285Sbrian    }
49528679Sbrian    return -1;
49628381Sbrian  default:
49728381Sbrian    // We don't have any information on this instruction.
49834536Sbrian    return -1;
49934536Sbrian  }
50047849Sbrian}
50128679Sbrian
50236285Sbrianvoid CostModelAnalysis::print(raw_ostream &OS, const Module*) const {
50318531Sbde  if (!F)
50436285Sbrian    return;
50536285Sbrian
50632017Sbrian  for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
50736285Sbrian    for (BasicBlock::iterator it = B->begin(), e = B->end(); it != e; ++it) {
50836285Sbrian      Instruction *Inst = it;
50936285Sbrian      unsigned Cost = getInstructionCost(Inst);
51036285Sbrian      if (Cost != (unsigned)-1)
51136285Sbrian        OS << "Cost Model: Found an estimated cost of " << Cost;
51236285Sbrian      else
51336285Sbrian        OS << "Cost Model: Unknown cost";
51428679Sbrian
51528679Sbrian      OS << " for instruction: "<< *Inst << "\n";
51649976Sbrian    }
51749976Sbrian  }
51849976Sbrian}
51949976Sbrian