1 //===-- C6000TargetTransformInfo.cpp - C6000 specific TTI pass ------------===//
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 /// \file
10 /// This file implements a TargetTransformInfo analysis pass specific to the
11 /// C6000 target machine. It uses the target's detailed information to provide
12 /// more precise answers to certain TTI queries, while letting the target
13 /// independent and default TTI implementations handle the rest.
14 ///
15 //===----------------------------------------------------------------------===//
17 #include "C6000.h"
18 #include "llvm/Analysis/LoopInfo.h"
19 #include "llvm/Analysis/TargetTransformInfo.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Target/CostTable.h"
22 #include "llvm/Target/TargetLowering.h"
23 using namespace llvm;
25 #define DEBUG_TYPE "c6000tti"
27 // Declare the pass initialization routine locally as target-specific passes
28 // don't have a target-wide initialization entry point, and so we rely on the
29 // pass constructor initialization.
30 namespace llvm {
31 void initializeC6000TTIPass(PassRegistry &);
32 }
34 namespace {
35 class C6000TTI final : public ImmutablePass, public TargetTransformInfo {
36 public:
37 C6000TTI() : ImmutablePass(ID) {
38 llvm_unreachable("This pass cannot be directly constructed");
39 }
41 C6000TTI(const C6000TargetMachine *TM)
42 : ImmutablePass(ID) {
43 initializeC6000TTIPass(*PassRegistry::getPassRegistry());
44 }
46 void initializePass() override {
47 pushTTIStack(this);
48 }
50 void getAnalysisUsage(AnalysisUsage &AU) const override {
51 TargetTransformInfo::getAnalysisUsage(AU);
52 }
54 /// Pass identification.
55 static char ID;
57 /// Provide necessary pointer adjustments for the two base classes.
58 void *getAdjustedAnalysisPointer(const void *ID) override {
59 if (ID == &TargetTransformInfo::ID)
60 return (TargetTransformInfo*)this;
61 return this;
62 }
64 /// \name Scalar TTI Implementations
65 /// @{
67 void getUnrollingPreferences(Loop *L,
68 UnrollingPreferences &UP) const override;
70 /// @}
72 /// \name Vector TTI Implementations
73 /// @{
75 unsigned getNumberOfRegisters(bool Vector) const override {
76 if (Vector)
77 return 16;
79 return 64;
80 }
82 unsigned getRegisterBitWidth(bool Vector) const override {
83 return 32;
84 }
86 unsigned getMaximumUnrollFactor() const override {
87 return 4;
88 }
90 unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
91 unsigned AddressSpace) const override;
92 };
94 } // end anonymous namespace
96 INITIALIZE_AG_PASS(C6000TTI, TargetTransformInfo, "c6000tti",
97 "C6000 Target Transform Info", true, true, false)
98 char C6000TTI::ID = 0;
100 ImmutablePass *
101 llvm::createC6000TargetTransformInfoPass(const C6000TargetMachine *TM) {
102 return new C6000TTI(TM);
103 }
105 void C6000TTI::getUnrollingPreferences(Loop *L,
106 UnrollingPreferences &UP) const {
107 // Scan the loop: don't unroll loops with calls.
108 for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
109 I != E; ++I) {
110 BasicBlock *BB = *I;
112 for (BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE; ++J)
113 if (isa<CallInst>(J) || isa<InvokeInst>(J)) {
114 ImmutableCallSite CS(J);
115 if (const Function *F = CS.getCalledFunction()) {
116 if (!TopTTI->isLoweredToCall(F))
117 continue;
118 }
120 return;
121 }
122 }
124 // Enable runtime and partial unrolling
125 UP.Partial = UP.Runtime = true;
126 }
128 unsigned C6000TTI::getMemoryOpCost(unsigned Opcode, Type *Src,
129 unsigned Alignment,
130 unsigned AddressSpace) const {
131 // TODO: implement correctly...
132 return 1;
133 }