blob: 764e8b8b7889cca0d13360d543ddfee53d1253c9 [file] [log] [blame]
Eugene Zelenko52889212017-08-01 21:20:10 +00001//===- HexagonTargetTransformInfo.cpp - Hexagon specific TTI pass ---------===//
Krzysztof Parzyszek73e66f32015-08-05 18:35:37 +00002//
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/// \file
9/// This file implements a TargetTransformInfo analysis pass specific to the
10/// Hexagon target machine. It uses the target's detailed information to provide
11/// more precise answers to certain TTI queries, while letting the target
12/// independent and default TTI implementations handle the rest.
13///
14//===----------------------------------------------------------------------===//
15
16#include "HexagonTargetTransformInfo.h"
Eugene Zelenko52889212017-08-01 21:20:10 +000017#include "HexagonSubtarget.h"
18#include "llvm/Analysis/TargetTransformInfo.h"
19#include "llvm/IR/InstrTypes.h"
Krzysztof Parzyszekdb019ae2016-08-19 14:22:07 +000020#include "llvm/IR/Instructions.h"
Eugene Zelenko52889212017-08-01 21:20:10 +000021#include "llvm/IR/User.h"
22#include "llvm/Support/Casting.h"
23#include "llvm/Support/CommandLine.h"
Ikhlas Ajbar1376d932018-04-03 22:55:09 +000024#include "llvm/Transforms/Utils/UnrollLoop.h"
Krzysztof Parzyszek73e66f32015-08-05 18:35:37 +000025
26using namespace llvm;
27
28#define DEBUG_TYPE "hexagontti"
29
Krzysztof Parzyszek0a15d242018-03-27 17:07:52 +000030static cl::opt<bool> HexagonAutoHVX("hexagon-autohvx", cl::init(false),
31 cl::Hidden, cl::desc("Enable loop vectorizer for HVX"));
32
Sumanth Gundapanenid2dd79b2017-06-30 20:54:24 +000033static cl::opt<bool> EmitLookupTables("hexagon-emit-lookup-tables",
34 cl::init(true), cl::Hidden,
35 cl::desc("Control lookup table emission on Hexagon target"));
36
Krzysztof Parzyszek73e66f32015-08-05 18:35:37 +000037TargetTransformInfo::PopcntSupportKind
38HexagonTTIImpl::getPopcntSupport(unsigned IntTyWidthInBit) const {
39 // Return Fast Hardware support as every input < 64 bits will be promoted
40 // to 64 bits.
41 return TargetTransformInfo::PSK_FastHardware;
42}
43
44// The Hexagon target can unroll loops with run-time trip counts.
Geoff Berry66d9bdb2017-06-28 15:53:17 +000045void HexagonTTIImpl::getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
Krzysztof Parzyszek73e66f32015-08-05 18:35:37 +000046 TTI::UnrollingPreferences &UP) {
47 UP.Runtime = UP.Partial = true;
Ikhlas Ajbarb7322e82018-04-03 03:39:43 +000048 // Only try to peel innermost loops with small runtime trip counts.
Ikhlas Ajbar1376d932018-04-03 22:55:09 +000049 if (L && L->empty() && canPeel(L) &&
Ikhlas Ajbarb7322e82018-04-03 03:39:43 +000050 SE.getSmallConstantTripCount(L) == 0 &&
51 SE.getSmallConstantMaxTripCount(L) > 0 &&
52 SE.getSmallConstantMaxTripCount(L) <= 5) {
53 UP.PeelCount = 2;
54 }
Krzysztof Parzyszek73e66f32015-08-05 18:35:37 +000055}
56
Krzysztof Parzyszek56f0fc42018-03-26 15:32:03 +000057bool HexagonTTIImpl::shouldFavorPostInc() const {
58 return true;
59}
60
Krzysztof Parzyszek0a15d242018-03-27 17:07:52 +000061unsigned HexagonTTIImpl::getNumberOfRegisters(bool Vector) const {
62 if (Vector)
63 return HexagonAutoHVX && getST()->useHVXOps() ? 32 : 0;
64 return 32;
65}
66
67unsigned HexagonTTIImpl::getMaxInterleaveFactor(unsigned VF) {
68 return HexagonAutoHVX && getST()->useHVXOps() ? 64 : 0;
69}
70
71unsigned HexagonTTIImpl::getRegisterBitWidth(bool Vector) const {
72 return Vector ? getMinVectorRegisterBitWidth() : 32;
73}
74
75unsigned HexagonTTIImpl::getMinVectorRegisterBitWidth() const {
76 return getST()->useHVXOps() ? getST()->getVectorLength()*8 : 0;
77}
78
Krzysztof Parzyszekdfed9412018-04-13 20:16:32 +000079unsigned HexagonTTIImpl::getMinimumVF(unsigned ElemWidth) const {
80 return (8 * getST()->getVectorLength()) / ElemWidth;
81}
82
Krzysztof Parzyszek0a15d242018-03-27 17:07:52 +000083unsigned HexagonTTIImpl::getMemoryOpCost(unsigned Opcode, Type *Src,
84 unsigned Alignment, unsigned AddressSpace, const Instruction *I) {
85 if (Opcode == Instruction::Load && Src->isVectorTy()) {
86 VectorType *VecTy = cast<VectorType>(Src);
87 unsigned VecWidth = VecTy->getBitWidth();
88 if (VecWidth > 64) {
89 // Assume that vectors longer than 64 bits are meant for HVX.
90 if (getNumberOfRegisters(true) > 0) {
91 if (VecWidth % getRegisterBitWidth(true) == 0)
92 return 1;
93 }
94 unsigned AlignWidth = 8 * std::max(1u, Alignment);
95 unsigned NumLoads = alignTo(VecWidth, AlignWidth) / AlignWidth;
96 return 3*NumLoads;
97 }
98 }
99 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace, I);
Krzysztof Parzyszek73e66f32015-08-05 18:35:37 +0000100}
Krzysztof Parzyszekd3d0a4b2016-07-22 14:22:43 +0000101
102unsigned HexagonTTIImpl::getPrefetchDistance() const {
103 return getST()->getL1PrefetchDistance();
104}
105
106unsigned HexagonTTIImpl::getCacheLineSize() const {
107 return getST()->getL1CacheLineSize();
108}
Krzysztof Parzyszekdb019ae2016-08-19 14:22:07 +0000109
Evgeny Astigeevich70ed78e2017-06-29 13:42:12 +0000110int HexagonTTIImpl::getUserCost(const User *U,
111 ArrayRef<const Value *> Operands) {
Krzysztof Parzyszek0a15d242018-03-27 17:07:52 +0000112 auto isCastFoldedIntoLoad = [this](const CastInst *CI) -> bool {
Krzysztof Parzyszekdb019ae2016-08-19 14:22:07 +0000113 if (!CI->isIntegerCast())
114 return false;
Krzysztof Parzyszek0a15d242018-03-27 17:07:52 +0000115 // Only extensions from an integer type shorter than 32-bit to i32
116 // can be folded into the load.
117 const DataLayout &DL = getDataLayout();
118 unsigned SBW = DL.getTypeSizeInBits(CI->getSrcTy());
119 unsigned DBW = DL.getTypeSizeInBits(CI->getDestTy());
120 if (DBW != 32 || SBW >= DBW)
121 return false;
122
Krzysztof Parzyszekdb019ae2016-08-19 14:22:07 +0000123 const LoadInst *LI = dyn_cast<const LoadInst>(CI->getOperand(0));
124 // Technically, this code could allow multiple uses of the load, and
125 // check if all the uses are the same extension operation, but this
126 // should be sufficient for most cases.
Krzysztof Parzyszek0a15d242018-03-27 17:07:52 +0000127 return LI && LI->hasOneUse();
Krzysztof Parzyszekdb019ae2016-08-19 14:22:07 +0000128 };
129
130 if (const CastInst *CI = dyn_cast<const CastInst>(U))
131 if (isCastFoldedIntoLoad(CI))
132 return TargetTransformInfo::TCC_Free;
Evgeny Astigeevich70ed78e2017-06-29 13:42:12 +0000133 return BaseT::getUserCost(U, Operands);
Krzysztof Parzyszekdb019ae2016-08-19 14:22:07 +0000134}
Sumanth Gundapanenid2dd79b2017-06-30 20:54:24 +0000135
136bool HexagonTTIImpl::shouldBuildLookupTables() const {
Krzysztof Parzyszek56f0fc42018-03-26 15:32:03 +0000137 return EmitLookupTables;
Sumanth Gundapanenid2dd79b2017-06-30 20:54:24 +0000138}