1259698Sdim//===-- AMDGPUTargetTransformInfo.cpp - AMDGPU specific TTI pass ---------===//
2259698Sdim//
3259698Sdim//                     The LLVM Compiler Infrastructure
4259698Sdim//
5259698Sdim// This file is distributed under the University of Illinois Open Source
6259698Sdim// License. See LICENSE.TXT for details.
7259698Sdim//
8259698Sdim//===----------------------------------------------------------------------===//
9259698Sdim//
10259698Sdim// \file
11259698Sdim// This file implements a TargetTransformInfo analysis pass specific to the
12259698Sdim// AMDGPU target machine. It uses the target's detailed information to provide
13259698Sdim// more precise answers to certain TTI queries, while letting the target
14259698Sdim// independent and default TTI implementations handle the rest.
15259698Sdim//
16259698Sdim//===----------------------------------------------------------------------===//
17259698Sdim
18259698Sdim#define DEBUG_TYPE "AMDGPUtti"
19259698Sdim#include "AMDGPU.h"
20259698Sdim#include "AMDGPUTargetMachine.h"
21259698Sdim#include "llvm/Analysis/TargetTransformInfo.h"
22259698Sdim#include "llvm/Support/Debug.h"
23259698Sdim#include "llvm/Target/TargetLowering.h"
24259698Sdim#include "llvm/Target/CostTable.h"
25259698Sdimusing namespace llvm;
26259698Sdim
27259698Sdim// Declare the pass initialization routine locally as target-specific passes
28259698Sdim// don't have a target-wide initialization entry point, and so we rely on the
29259698Sdim// pass constructor initialization.
30259698Sdimnamespace llvm {
31259698Sdimvoid initializeAMDGPUTTIPass(PassRegistry &);
32259698Sdim}
33259698Sdim
34259698Sdimnamespace {
35259698Sdim
36259698Sdimclass AMDGPUTTI : public ImmutablePass, public TargetTransformInfo {
37259698Sdim  const AMDGPUTargetMachine *TM;
38259698Sdim  const AMDGPUSubtarget *ST;
39259698Sdim  const AMDGPUTargetLowering *TLI;
40259698Sdim
41259698Sdim  /// Estimate the overhead of scalarizing an instruction. Insert and Extract
42259698Sdim  /// are set if the result needs to be inserted and/or extracted from vectors.
43259698Sdim  unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const;
44259698Sdim
45259698Sdimpublic:
46259698Sdim  AMDGPUTTI() : ImmutablePass(ID), TM(0), ST(0), TLI(0) {
47259698Sdim    llvm_unreachable("This pass cannot be directly constructed");
48259698Sdim  }
49259698Sdim
50259698Sdim  AMDGPUTTI(const AMDGPUTargetMachine *TM)
51259698Sdim      : ImmutablePass(ID), TM(TM), ST(TM->getSubtargetImpl()),
52259698Sdim        TLI(TM->getTargetLowering()) {
53259698Sdim    initializeAMDGPUTTIPass(*PassRegistry::getPassRegistry());
54259698Sdim  }
55259698Sdim
56259698Sdim  virtual void initializePass() { pushTTIStack(this); }
57259698Sdim
58259698Sdim  virtual void finalizePass() { popTTIStack(); }
59259698Sdim
60259698Sdim  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
61259698Sdim    TargetTransformInfo::getAnalysisUsage(AU);
62259698Sdim  }
63259698Sdim
64259698Sdim  /// Pass identification.
65259698Sdim  static char ID;
66259698Sdim
67259698Sdim  /// Provide necessary pointer adjustments for the two base classes.
68259698Sdim  virtual void *getAdjustedAnalysisPointer(const void *ID) {
69259698Sdim    if (ID == &TargetTransformInfo::ID)
70259698Sdim      return (TargetTransformInfo *)this;
71259698Sdim    return this;
72259698Sdim  }
73259698Sdim
74259698Sdim  virtual bool hasBranchDivergence() const;
75259698Sdim
76259698Sdim  /// @}
77259698Sdim};
78259698Sdim
79259698Sdim} // end anonymous namespace
80259698Sdim
81259698SdimINITIALIZE_AG_PASS(AMDGPUTTI, TargetTransformInfo, "AMDGPUtti",
82259698Sdim                   "AMDGPU Target Transform Info", true, true, false)
83259698Sdimchar AMDGPUTTI::ID = 0;
84259698Sdim
85259698SdimImmutablePass *
86259698Sdimllvm::createAMDGPUTargetTransformInfoPass(const AMDGPUTargetMachine *TM) {
87259698Sdim  return new AMDGPUTTI(TM);
88259698Sdim}
89259698Sdim
90259698Sdimbool AMDGPUTTI::hasBranchDivergence() const { return true; }
91