| Chandler Carruth | d3e7355 | 2013-01-07 03:08:10 +0000 | [diff] [blame] | 1 | //===- llvm/Analysis/TargetTransformInfo.cpp ------------------------------===// | 
| Nadav Rotem | 5dc203e | 2012-10-18 23:22:48 +0000 | [diff] [blame] | 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 |  | 
| Chandler Carruth | d3e7355 | 2013-01-07 03:08:10 +0000 | [diff] [blame] | 10 | #include "llvm/Analysis/TargetTransformInfo.h" | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 11 | #include "llvm/Analysis/TargetTransformInfoImpl.h" | 
| Chandler Carruth | 219b89b | 2014-03-04 11:01:28 +0000 | [diff] [blame] | 12 | #include "llvm/IR/CallSite.h" | 
| Chandler Carruth | 511aa76 | 2013-01-21 01:27:39 +0000 | [diff] [blame] | 13 | #include "llvm/IR/DataLayout.h" | 
| Chandler Carruth | 511aa76 | 2013-01-21 01:27:39 +0000 | [diff] [blame] | 14 | #include "llvm/IR/Instruction.h" | 
| Chandler Carruth | 511aa76 | 2013-01-21 01:27:39 +0000 | [diff] [blame] | 15 | #include "llvm/IR/Instructions.h" | 
| Chandler Carruth | 8a8cd2b | 2014-01-07 11:48:04 +0000 | [diff] [blame] | 16 | #include "llvm/IR/IntrinsicInst.h" | 
| Chandler Carruth | e038552 | 2015-02-01 10:11:22 +0000 | [diff] [blame] | 17 | #include "llvm/IR/Module.h" | 
| Chandler Carruth | 8a8cd2b | 2014-01-07 11:48:04 +0000 | [diff] [blame] | 18 | #include "llvm/IR/Operator.h" | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 19 | #include "llvm/IR/PatternMatch.h" | 
| Sean Fertile | 9cd1cdf | 2017-07-07 02:00:06 +0000 | [diff] [blame] | 20 | #include "llvm/Support/CommandLine.h" | 
| Nadav Rotem | 5dc203e | 2012-10-18 23:22:48 +0000 | [diff] [blame] | 21 | #include "llvm/Support/ErrorHandling.h" | 
| Benjamin Kramer | 82de7d3 | 2016-05-27 14:27:24 +0000 | [diff] [blame] | 22 | #include <utility> | 
| Nadav Rotem | 5dc203e | 2012-10-18 23:22:48 +0000 | [diff] [blame] | 23 |  | 
|  | 24 | using namespace llvm; | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 25 | using namespace PatternMatch; | 
| Nadav Rotem | 5dc203e | 2012-10-18 23:22:48 +0000 | [diff] [blame] | 26 |  | 
| Chandler Carruth | f1221bd | 2014-04-22 02:48:03 +0000 | [diff] [blame] | 27 | #define DEBUG_TYPE "tti" | 
|  | 28 |  | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 29 | static cl::opt<bool> EnableReduxCost("costmodel-reduxcost", cl::init(false), | 
|  | 30 | cl::Hidden, | 
|  | 31 | cl::desc("Recognize reduction patterns.")); | 
|  | 32 |  | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 33 | namespace { | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 34 | /// No-op implementation of the TTI interface using the utility base | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 35 | /// classes. | 
|  | 36 | /// | 
|  | 37 | /// This is used when no target specific information is available. | 
|  | 38 | struct NoTTIImpl : TargetTransformInfoImplCRTPBase<NoTTIImpl> { | 
| Mehdi Amini | 5010ebf | 2015-07-09 02:08:42 +0000 | [diff] [blame] | 39 | explicit NoTTIImpl(const DataLayout &DL) | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 40 | : TargetTransformInfoImplCRTPBase<NoTTIImpl>(DL) {} | 
|  | 41 | }; | 
|  | 42 | } | 
|  | 43 |  | 
| Mehdi Amini | 5010ebf | 2015-07-09 02:08:42 +0000 | [diff] [blame] | 44 | TargetTransformInfo::TargetTransformInfo(const DataLayout &DL) | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 45 | : TTIImpl(new Model<NoTTIImpl>(NoTTIImpl(DL))) {} | 
|  | 46 |  | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 47 | TargetTransformInfo::~TargetTransformInfo() {} | 
| Nadav Rotem | 5dc203e | 2012-10-18 23:22:48 +0000 | [diff] [blame] | 48 |  | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 49 | TargetTransformInfo::TargetTransformInfo(TargetTransformInfo &&Arg) | 
|  | 50 | : TTIImpl(std::move(Arg.TTIImpl)) {} | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 51 |  | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 52 | TargetTransformInfo &TargetTransformInfo::operator=(TargetTransformInfo &&RHS) { | 
|  | 53 | TTIImpl = std::move(RHS.TTIImpl); | 
|  | 54 | return *this; | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 55 | } | 
|  | 56 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 57 | int TargetTransformInfo::getOperationCost(unsigned Opcode, Type *Ty, | 
|  | 58 | Type *OpTy) const { | 
|  | 59 | int Cost = TTIImpl->getOperationCost(Opcode, Ty, OpTy); | 
|  | 60 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 61 | return Cost; | 
| Chandler Carruth | 511aa76 | 2013-01-21 01:27:39 +0000 | [diff] [blame] | 62 | } | 
|  | 63 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 64 | int TargetTransformInfo::getCallCost(FunctionType *FTy, int NumArgs) const { | 
|  | 65 | int Cost = TTIImpl->getCallCost(FTy, NumArgs); | 
|  | 66 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 67 | return Cost; | 
| Chandler Carruth | 0ba8db4 | 2013-01-22 11:26:02 +0000 | [diff] [blame] | 68 | } | 
|  | 69 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 70 | int TargetTransformInfo::getCallCost(const Function *F, | 
|  | 71 | ArrayRef<const Value *> Arguments) const { | 
|  | 72 | int Cost = TTIImpl->getCallCost(F, Arguments); | 
|  | 73 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 74 | return Cost; | 
| Chandler Carruth | 0ba8db4 | 2013-01-22 11:26:02 +0000 | [diff] [blame] | 75 | } | 
|  | 76 |  | 
| Justin Lebar | 8650a4d | 2016-04-15 01:38:48 +0000 | [diff] [blame] | 77 | unsigned TargetTransformInfo::getInliningThresholdMultiplier() const { | 
|  | 78 | return TTIImpl->getInliningThresholdMultiplier(); | 
|  | 79 | } | 
|  | 80 |  | 
| Jingyue Wu | 15f3e82 | 2016-07-08 21:48:05 +0000 | [diff] [blame] | 81 | int TargetTransformInfo::getGEPCost(Type *PointeeType, const Value *Ptr, | 
|  | 82 | ArrayRef<const Value *> Operands) const { | 
|  | 83 | return TTIImpl->getGEPCost(PointeeType, Ptr, Operands); | 
|  | 84 | } | 
|  | 85 |  | 
| Haicheng Wu | abdef9e | 2017-07-15 02:12:16 +0000 | [diff] [blame] | 86 | int TargetTransformInfo::getExtCost(const Instruction *I, | 
|  | 87 | const Value *Src) const { | 
|  | 88 | return TTIImpl->getExtCost(I, Src); | 
|  | 89 | } | 
|  | 90 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 91 | int TargetTransformInfo::getIntrinsicCost( | 
|  | 92 | Intrinsic::ID IID, Type *RetTy, ArrayRef<const Value *> Arguments) const { | 
|  | 93 | int Cost = TTIImpl->getIntrinsicCost(IID, RetTy, Arguments); | 
|  | 94 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 95 | return Cost; | 
| Chandler Carruth | 0ba8db4 | 2013-01-22 11:26:02 +0000 | [diff] [blame] | 96 | } | 
|  | 97 |  | 
| Jun Bum Lim | 919f9e8 | 2017-04-28 16:04:03 +0000 | [diff] [blame] | 98 | unsigned | 
|  | 99 | TargetTransformInfo::getEstimatedNumberOfCaseClusters(const SwitchInst &SI, | 
|  | 100 | unsigned &JTSize) const { | 
|  | 101 | return TTIImpl->getEstimatedNumberOfCaseClusters(SI, JTSize); | 
|  | 102 | } | 
|  | 103 |  | 
| Evgeny Astigeevich | 70ed78e | 2017-06-29 13:42:12 +0000 | [diff] [blame] | 104 | int TargetTransformInfo::getUserCost(const User *U, | 
|  | 105 | ArrayRef<const Value *> Operands) const { | 
|  | 106 | int Cost = TTIImpl->getUserCost(U, Operands); | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 107 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 108 | return Cost; | 
| Chandler Carruth | 511aa76 | 2013-01-21 01:27:39 +0000 | [diff] [blame] | 109 | } | 
|  | 110 |  | 
| Tom Stellard | 8b1e021 | 2013-07-27 00:01:07 +0000 | [diff] [blame] | 111 | bool TargetTransformInfo::hasBranchDivergence() const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 112 | return TTIImpl->hasBranchDivergence(); | 
| Tom Stellard | 8b1e021 | 2013-07-27 00:01:07 +0000 | [diff] [blame] | 113 | } | 
|  | 114 |  | 
| Jingyue Wu | 5da831c | 2015-04-10 05:03:50 +0000 | [diff] [blame] | 115 | bool TargetTransformInfo::isSourceOfDivergence(const Value *V) const { | 
|  | 116 | return TTIImpl->isSourceOfDivergence(V); | 
|  | 117 | } | 
|  | 118 |  | 
| Alexander Timofeev | 0f9c84c | 2017-06-15 19:33:10 +0000 | [diff] [blame] | 119 | bool llvm::TargetTransformInfo::isAlwaysUniform(const Value *V) const { | 
|  | 120 | return TTIImpl->isAlwaysUniform(V); | 
|  | 121 | } | 
|  | 122 |  | 
| Matt Arsenault | 42b6478 | 2017-01-30 23:02:12 +0000 | [diff] [blame] | 123 | unsigned TargetTransformInfo::getFlatAddressSpace() const { | 
|  | 124 | return TTIImpl->getFlatAddressSpace(); | 
|  | 125 | } | 
|  | 126 |  | 
| Chandler Carruth | 0ba8db4 | 2013-01-22 11:26:02 +0000 | [diff] [blame] | 127 | bool TargetTransformInfo::isLoweredToCall(const Function *F) const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 128 | return TTIImpl->isLoweredToCall(F); | 
| Chandler Carruth | 0ba8db4 | 2013-01-22 11:26:02 +0000 | [diff] [blame] | 129 | } | 
|  | 130 |  | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 131 | void TargetTransformInfo::getUnrollingPreferences( | 
| Geoff Berry | 66d9bdb | 2017-06-28 15:53:17 +0000 | [diff] [blame] | 132 | Loop *L, ScalarEvolution &SE, UnrollingPreferences &UP) const { | 
|  | 133 | return TTIImpl->getUnrollingPreferences(L, SE, UP); | 
| Hal Finkel | 8f2e700 | 2013-09-11 19:25:43 +0000 | [diff] [blame] | 134 | } | 
|  | 135 |  | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 136 | bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 137 | return TTIImpl->isLegalAddImmediate(Imm); | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 138 | } | 
|  | 139 |  | 
|  | 140 | bool TargetTransformInfo::isLegalICmpImmediate(int64_t Imm) const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 141 | return TTIImpl->isLegalICmpImmediate(Imm); | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 142 | } | 
|  | 143 |  | 
|  | 144 | bool TargetTransformInfo::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, | 
|  | 145 | int64_t BaseOffset, | 
|  | 146 | bool HasBaseReg, | 
| Matt Arsenault | e83379e | 2015-06-07 20:12:03 +0000 | [diff] [blame] | 147 | int64_t Scale, | 
| Jonas Paulsson | 024e319 | 2017-07-21 11:59:37 +0000 | [diff] [blame] | 148 | unsigned AddrSpace, | 
|  | 149 | Instruction *I) const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 150 | return TTIImpl->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, | 
| Jonas Paulsson | 024e319 | 2017-07-21 11:59:37 +0000 | [diff] [blame] | 151 | Scale, AddrSpace, I); | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 152 | } | 
|  | 153 |  | 
| Evgeny Stupachenko | f2b3b46 | 2017-06-05 23:37:00 +0000 | [diff] [blame] | 154 | bool TargetTransformInfo::isLSRCostLess(LSRCost &C1, LSRCost &C2) const { | 
|  | 155 | return TTIImpl->isLSRCostLess(C1, C2); | 
|  | 156 | } | 
|  | 157 |  | 
| Sanjay Patel | d7c702b | 2018-02-05 23:43:05 +0000 | [diff] [blame] | 158 | bool TargetTransformInfo::canMacroFuseCmp() const { | 
|  | 159 | return TTIImpl->canMacroFuseCmp(); | 
|  | 160 | } | 
|  | 161 |  | 
| Krzysztof Parzyszek | 0b377e0 | 2018-03-26 13:10:09 +0000 | [diff] [blame] | 162 | bool TargetTransformInfo::shouldFavorPostInc() const { | 
|  | 163 | return TTIImpl->shouldFavorPostInc(); | 
|  | 164 | } | 
|  | 165 |  | 
| Elena Demikhovsky | 20662e3 | 2015-10-19 07:43:38 +0000 | [diff] [blame] | 166 | bool TargetTransformInfo::isLegalMaskedStore(Type *DataType) const { | 
|  | 167 | return TTIImpl->isLegalMaskedStore(DataType); | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 168 | } | 
|  | 169 |  | 
| Elena Demikhovsky | 20662e3 | 2015-10-19 07:43:38 +0000 | [diff] [blame] | 170 | bool TargetTransformInfo::isLegalMaskedLoad(Type *DataType) const { | 
|  | 171 | return TTIImpl->isLegalMaskedLoad(DataType); | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 172 | } | 
|  | 173 |  | 
| Elena Demikhovsky | 0928585 | 2015-10-25 15:37:55 +0000 | [diff] [blame] | 174 | bool TargetTransformInfo::isLegalMaskedGather(Type *DataType) const { | 
|  | 175 | return TTIImpl->isLegalMaskedGather(DataType); | 
|  | 176 | } | 
|  | 177 |  | 
|  | 178 | bool TargetTransformInfo::isLegalMaskedScatter(Type *DataType) const { | 
| Mohammed Agabaria | cef53dc | 2017-07-27 10:28:16 +0000 | [diff] [blame] | 179 | return TTIImpl->isLegalMaskedScatter(DataType); | 
| Elena Demikhovsky | 0928585 | 2015-10-25 15:37:55 +0000 | [diff] [blame] | 180 | } | 
|  | 181 |  | 
| Sanjay Patel | 6fd4391 | 2017-09-09 13:38:18 +0000 | [diff] [blame] | 182 | bool TargetTransformInfo::hasDivRemOp(Type *DataType, bool IsSigned) const { | 
|  | 183 | return TTIImpl->hasDivRemOp(DataType, IsSigned); | 
|  | 184 | } | 
|  | 185 |  | 
| Artem Belevich | cb8f632 | 2017-10-24 20:31:44 +0000 | [diff] [blame] | 186 | bool TargetTransformInfo::hasVolatileVariant(Instruction *I, | 
|  | 187 | unsigned AddrSpace) const { | 
|  | 188 | return TTIImpl->hasVolatileVariant(I, AddrSpace); | 
|  | 189 | } | 
|  | 190 |  | 
| Jonas Paulsson | 8624b7e | 2017-05-24 13:42:56 +0000 | [diff] [blame] | 191 | bool TargetTransformInfo::prefersVectorizedAddressing() const { | 
|  | 192 | return TTIImpl->prefersVectorizedAddressing(); | 
|  | 193 | } | 
|  | 194 |  | 
| Quentin Colombet | bf490d4 | 2013-05-31 21:29:03 +0000 | [diff] [blame] | 195 | int TargetTransformInfo::getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, | 
|  | 196 | int64_t BaseOffset, | 
|  | 197 | bool HasBaseReg, | 
| Matt Arsenault | e83379e | 2015-06-07 20:12:03 +0000 | [diff] [blame] | 198 | int64_t Scale, | 
|  | 199 | unsigned AddrSpace) const { | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 200 | int Cost = TTIImpl->getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg, | 
|  | 201 | Scale, AddrSpace); | 
|  | 202 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 203 | return Cost; | 
| Quentin Colombet | bf490d4 | 2013-05-31 21:29:03 +0000 | [diff] [blame] | 204 | } | 
|  | 205 |  | 
| Jonas Paulsson | 024e319 | 2017-07-21 11:59:37 +0000 | [diff] [blame] | 206 | bool TargetTransformInfo::LSRWithInstrQueries() const { | 
|  | 207 | return TTIImpl->LSRWithInstrQueries(); | 
|  | 208 | } | 
|  | 209 |  | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 210 | bool TargetTransformInfo::isTruncateFree(Type *Ty1, Type *Ty2) const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 211 | return TTIImpl->isTruncateFree(Ty1, Ty2); | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 212 | } | 
|  | 213 |  | 
| Chad Rosier | 5439005 | 2015-02-23 19:15:16 +0000 | [diff] [blame] | 214 | bool TargetTransformInfo::isProfitableToHoist(Instruction *I) const { | 
|  | 215 | return TTIImpl->isProfitableToHoist(I); | 
|  | 216 | } | 
|  | 217 |  | 
| David Blaikie | 8ad9a97 | 2018-03-28 22:28:50 +0000 | [diff] [blame] | 218 | bool TargetTransformInfo::useAA() const { return TTIImpl->useAA(); } | 
|  | 219 |  | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 220 | bool TargetTransformInfo::isTypeLegal(Type *Ty) const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 221 | return TTIImpl->isTypeLegal(Ty); | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 222 | } | 
|  | 223 |  | 
|  | 224 | unsigned TargetTransformInfo::getJumpBufAlignment() const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 225 | return TTIImpl->getJumpBufAlignment(); | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 226 | } | 
|  | 227 |  | 
|  | 228 | unsigned TargetTransformInfo::getJumpBufSize() const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 229 | return TTIImpl->getJumpBufSize(); | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 230 | } | 
|  | 231 |  | 
|  | 232 | bool TargetTransformInfo::shouldBuildLookupTables() const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 233 | return TTIImpl->shouldBuildLookupTables(); | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 234 | } | 
| Oliver Stannard | 4df1cc0 | 2016-10-07 08:48:24 +0000 | [diff] [blame] | 235 | bool TargetTransformInfo::shouldBuildLookupTablesForConstant(Constant *C) const { | 
|  | 236 | return TTIImpl->shouldBuildLookupTablesForConstant(C); | 
|  | 237 | } | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 238 |  | 
| Zaara Syeda | 1f59ae3 | 2018-01-30 16:17:22 +0000 | [diff] [blame] | 239 | bool TargetTransformInfo::useColdCCForColdCall(Function &F) const { | 
|  | 240 | return TTIImpl->useColdCCForColdCall(F); | 
|  | 241 | } | 
|  | 242 |  | 
| Jonas Paulsson | 8e2f948 | 2017-01-26 07:03:25 +0000 | [diff] [blame] | 243 | unsigned TargetTransformInfo:: | 
|  | 244 | getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const { | 
|  | 245 | return TTIImpl->getScalarizationOverhead(Ty, Insert, Extract); | 
|  | 246 | } | 
|  | 247 |  | 
|  | 248 | unsigned TargetTransformInfo:: | 
|  | 249 | getOperandsScalarizationOverhead(ArrayRef<const Value *> Args, | 
|  | 250 | unsigned VF) const { | 
|  | 251 | return TTIImpl->getOperandsScalarizationOverhead(Args, VF); | 
|  | 252 | } | 
|  | 253 |  | 
| Jonas Paulsson | da74ed4 | 2017-04-12 12:41:37 +0000 | [diff] [blame] | 254 | bool TargetTransformInfo::supportsEfficientVectorElementLoadStore() const { | 
|  | 255 | return TTIImpl->supportsEfficientVectorElementLoadStore(); | 
|  | 256 | } | 
|  | 257 |  | 
| Olivier Sallenave | 049d803 | 2015-03-06 23:12:04 +0000 | [diff] [blame] | 258 | bool TargetTransformInfo::enableAggressiveInterleaving(bool LoopHasReductions) const { | 
|  | 259 | return TTIImpl->enableAggressiveInterleaving(LoopHasReductions); | 
|  | 260 | } | 
|  | 261 |  | 
| Clement Courbet | b2c3eb8 | 2017-10-30 14:19:33 +0000 | [diff] [blame] | 262 | const TargetTransformInfo::MemCmpExpansionOptions * | 
|  | 263 | TargetTransformInfo::enableMemCmpExpansion(bool IsZeroCmp) const { | 
|  | 264 | return TTIImpl->enableMemCmpExpansion(IsZeroCmp); | 
| Zaara Syeda | 3a7578c | 2017-05-31 17:12:38 +0000 | [diff] [blame] | 265 | } | 
|  | 266 |  | 
| Silviu Baranga | 61bdc51 | 2015-08-10 14:50:54 +0000 | [diff] [blame] | 267 | bool TargetTransformInfo::enableInterleavedAccessVectorization() const { | 
|  | 268 | return TTIImpl->enableInterleavedAccessVectorization(); | 
|  | 269 | } | 
|  | 270 |  | 
| Renato Golin | 5cb666a | 2016-04-14 20:42:18 +0000 | [diff] [blame] | 271 | bool TargetTransformInfo::isFPVectorizationPotentiallyUnsafe() const { | 
|  | 272 | return TTIImpl->isFPVectorizationPotentiallyUnsafe(); | 
|  | 273 | } | 
|  | 274 |  | 
| Alina Sbirlea | 6f937b1 | 2016-08-04 16:38:44 +0000 | [diff] [blame] | 275 | bool TargetTransformInfo::allowsMisalignedMemoryAccesses(LLVMContext &Context, | 
|  | 276 | unsigned BitWidth, | 
| Alina Sbirlea | 327955e | 2016-07-11 20:46:17 +0000 | [diff] [blame] | 277 | unsigned AddressSpace, | 
|  | 278 | unsigned Alignment, | 
|  | 279 | bool *Fast) const { | 
| Alina Sbirlea | 6f937b1 | 2016-08-04 16:38:44 +0000 | [diff] [blame] | 280 | return TTIImpl->allowsMisalignedMemoryAccesses(Context, BitWidth, AddressSpace, | 
| Alina Sbirlea | 327955e | 2016-07-11 20:46:17 +0000 | [diff] [blame] | 281 | Alignment, Fast); | 
|  | 282 | } | 
|  | 283 |  | 
| Chandler Carruth | 50a36cd | 2013-01-07 03:16:03 +0000 | [diff] [blame] | 284 | TargetTransformInfo::PopcntSupportKind | 
|  | 285 | TargetTransformInfo::getPopcntSupport(unsigned IntTyWidthInBit) const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 286 | return TTIImpl->getPopcntSupport(IntTyWidthInBit); | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 287 | } | 
|  | 288 |  | 
| Richard Sandiford | 37cd6cf | 2013-08-23 10:27:02 +0000 | [diff] [blame] | 289 | bool TargetTransformInfo::haveFastSqrt(Type *Ty) const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 290 | return TTIImpl->haveFastSqrt(Ty); | 
| Richard Sandiford | 37cd6cf | 2013-08-23 10:27:02 +0000 | [diff] [blame] | 291 | } | 
|  | 292 |  | 
| Sanjay Patel | 0de1a4b | 2017-11-27 21:15:43 +0000 | [diff] [blame] | 293 | bool TargetTransformInfo::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const { | 
|  | 294 | return TTIImpl->isFCmpOrdCheaperThanFCmpZero(Ty); | 
|  | 295 | } | 
|  | 296 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 297 | int TargetTransformInfo::getFPOpCost(Type *Ty) const { | 
|  | 298 | int Cost = TTIImpl->getFPOpCost(Ty); | 
|  | 299 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 300 | return Cost; | 
| Cameron Esfahani | 17177d1 | 2015-02-05 02:09:33 +0000 | [diff] [blame] | 301 | } | 
|  | 302 |  | 
| Sjoerd Meijer | 38c2cd0 | 2016-07-14 07:44:20 +0000 | [diff] [blame] | 303 | int TargetTransformInfo::getIntImmCodeSizeCost(unsigned Opcode, unsigned Idx, | 
|  | 304 | const APInt &Imm, | 
|  | 305 | Type *Ty) const { | 
|  | 306 | int Cost = TTIImpl->getIntImmCodeSizeCost(Opcode, Idx, Imm, Ty); | 
|  | 307 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 308 | return Cost; | 
|  | 309 | } | 
|  | 310 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 311 | int TargetTransformInfo::getIntImmCost(const APInt &Imm, Type *Ty) const { | 
|  | 312 | int Cost = TTIImpl->getIntImmCost(Imm, Ty); | 
|  | 313 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 314 | return Cost; | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 315 | } | 
|  | 316 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 317 | int TargetTransformInfo::getIntImmCost(unsigned Opcode, unsigned Idx, | 
|  | 318 | const APInt &Imm, Type *Ty) const { | 
|  | 319 | int Cost = TTIImpl->getIntImmCost(Opcode, Idx, Imm, Ty); | 
|  | 320 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 321 | return Cost; | 
| Juergen Ributzka | f26beda | 2014-01-25 02:02:55 +0000 | [diff] [blame] | 322 | } | 
|  | 323 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 324 | int TargetTransformInfo::getIntImmCost(Intrinsic::ID IID, unsigned Idx, | 
|  | 325 | const APInt &Imm, Type *Ty) const { | 
|  | 326 | int Cost = TTIImpl->getIntImmCost(IID, Idx, Imm, Ty); | 
|  | 327 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 328 | return Cost; | 
| Juergen Ributzka | f26beda | 2014-01-25 02:02:55 +0000 | [diff] [blame] | 329 | } | 
|  | 330 |  | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 331 | unsigned TargetTransformInfo::getNumberOfRegisters(bool Vector) const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 332 | return TTIImpl->getNumberOfRegisters(Vector); | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 333 | } | 
|  | 334 |  | 
| Nadav Rotem | b1791a7 | 2013-01-09 22:29:00 +0000 | [diff] [blame] | 335 | unsigned TargetTransformInfo::getRegisterBitWidth(bool Vector) const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 336 | return TTIImpl->getRegisterBitWidth(Vector); | 
| Nadav Rotem | b1791a7 | 2013-01-09 22:29:00 +0000 | [diff] [blame] | 337 | } | 
|  | 338 |  | 
| Adam Nemet | e29686e | 2017-05-15 21:15:01 +0000 | [diff] [blame] | 339 | unsigned TargetTransformInfo::getMinVectorRegisterBitWidth() const { | 
|  | 340 | return TTIImpl->getMinVectorRegisterBitWidth(); | 
|  | 341 | } | 
|  | 342 |  | 
| Krzysztof Parzyszek | 5d93fdf | 2018-03-27 16:14:11 +0000 | [diff] [blame] | 343 | bool TargetTransformInfo::shouldMaximizeVectorBandwidth(bool OptSize) const { | 
|  | 344 | return TTIImpl->shouldMaximizeVectorBandwidth(OptSize); | 
|  | 345 | } | 
|  | 346 |  | 
| Krzysztof Parzyszek | dfed941 | 2018-04-13 20:16:32 +0000 | [diff] [blame] | 347 | unsigned TargetTransformInfo::getMinimumVF(unsigned ElemWidth) const { | 
|  | 348 | return TTIImpl->getMinimumVF(ElemWidth); | 
|  | 349 | } | 
|  | 350 |  | 
| Jun Bum Lim | dee5565 | 2017-04-03 19:20:07 +0000 | [diff] [blame] | 351 | bool TargetTransformInfo::shouldConsiderAddressTypePromotion( | 
|  | 352 | const Instruction &I, bool &AllowPromotionWithoutCommonHeader) const { | 
|  | 353 | return TTIImpl->shouldConsiderAddressTypePromotion( | 
|  | 354 | I, AllowPromotionWithoutCommonHeader); | 
|  | 355 | } | 
|  | 356 |  | 
| Adam Nemet | af76110 | 2016-01-21 18:28:36 +0000 | [diff] [blame] | 357 | unsigned TargetTransformInfo::getCacheLineSize() const { | 
|  | 358 | return TTIImpl->getCacheLineSize(); | 
|  | 359 | } | 
|  | 360 |  | 
| Tobias Grosser | d7eb619 | 2017-08-24 09:46:25 +0000 | [diff] [blame] | 361 | llvm::Optional<unsigned> TargetTransformInfo::getCacheSize(CacheLevel Level) | 
|  | 362 | const { | 
|  | 363 | return TTIImpl->getCacheSize(Level); | 
|  | 364 | } | 
|  | 365 |  | 
|  | 366 | llvm::Optional<unsigned> TargetTransformInfo::getCacheAssociativity( | 
|  | 367 | CacheLevel Level) const { | 
|  | 368 | return TTIImpl->getCacheAssociativity(Level); | 
|  | 369 | } | 
|  | 370 |  | 
| Adam Nemet | dadfbb5 | 2016-01-27 22:21:25 +0000 | [diff] [blame] | 371 | unsigned TargetTransformInfo::getPrefetchDistance() const { | 
|  | 372 | return TTIImpl->getPrefetchDistance(); | 
|  | 373 | } | 
|  | 374 |  | 
| Adam Nemet | 6d8beec | 2016-03-18 00:27:38 +0000 | [diff] [blame] | 375 | unsigned TargetTransformInfo::getMinPrefetchStride() const { | 
|  | 376 | return TTIImpl->getMinPrefetchStride(); | 
|  | 377 | } | 
|  | 378 |  | 
| Adam Nemet | 709e304 | 2016-03-18 00:27:43 +0000 | [diff] [blame] | 379 | unsigned TargetTransformInfo::getMaxPrefetchIterationsAhead() const { | 
|  | 380 | return TTIImpl->getMaxPrefetchIterationsAhead(); | 
|  | 381 | } | 
|  | 382 |  | 
| Wei Mi | 062c744 | 2015-05-06 17:12:25 +0000 | [diff] [blame] | 383 | unsigned TargetTransformInfo::getMaxInterleaveFactor(unsigned VF) const { | 
|  | 384 | return TTIImpl->getMaxInterleaveFactor(VF); | 
| Nadav Rotem | b696c36 | 2013-01-09 01:15:42 +0000 | [diff] [blame] | 385 | } | 
|  | 386 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 387 | int TargetTransformInfo::getArithmeticInstrCost( | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 388 | unsigned Opcode, Type *Ty, OperandValueKind Opd1Info, | 
|  | 389 | OperandValueKind Opd2Info, OperandValueProperties Opd1PropInfo, | 
| Mohammed Agabaria | 2c96c43 | 2017-01-11 08:23:37 +0000 | [diff] [blame] | 390 | OperandValueProperties Opd2PropInfo, | 
|  | 391 | ArrayRef<const Value *> Args) const { | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 392 | int Cost = TTIImpl->getArithmeticInstrCost(Opcode, Ty, Opd1Info, Opd2Info, | 
| Mohammed Agabaria | 2c96c43 | 2017-01-11 08:23:37 +0000 | [diff] [blame] | 393 | Opd1PropInfo, Opd2PropInfo, Args); | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 394 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 395 | return Cost; | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 396 | } | 
|  | 397 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 398 | int TargetTransformInfo::getShuffleCost(ShuffleKind Kind, Type *Ty, int Index, | 
|  | 399 | Type *SubTp) const { | 
|  | 400 | int Cost = TTIImpl->getShuffleCost(Kind, Ty, Index, SubTp); | 
|  | 401 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 402 | return Cost; | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 403 | } | 
|  | 404 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 405 | int TargetTransformInfo::getCastInstrCost(unsigned Opcode, Type *Dst, | 
| Jonas Paulsson | fccc7d6 | 2017-04-12 11:49:08 +0000 | [diff] [blame] | 406 | Type *Src, const Instruction *I) const { | 
|  | 407 | assert ((I == nullptr || I->getOpcode() == Opcode) && | 
|  | 408 | "Opcode should reflect passed instruction."); | 
|  | 409 | int Cost = TTIImpl->getCastInstrCost(Opcode, Dst, Src, I); | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 410 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 411 | return Cost; | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 412 | } | 
|  | 413 |  | 
| Matthew Simpson | e5dfb08 | 2016-04-27 15:20:21 +0000 | [diff] [blame] | 414 | int TargetTransformInfo::getExtractWithExtendCost(unsigned Opcode, Type *Dst, | 
|  | 415 | VectorType *VecTy, | 
|  | 416 | unsigned Index) const { | 
|  | 417 | int Cost = TTIImpl->getExtractWithExtendCost(Opcode, Dst, VecTy, Index); | 
|  | 418 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 419 | return Cost; | 
|  | 420 | } | 
|  | 421 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 422 | int TargetTransformInfo::getCFInstrCost(unsigned Opcode) const { | 
|  | 423 | int Cost = TTIImpl->getCFInstrCost(Opcode); | 
|  | 424 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 425 | return Cost; | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 426 | } | 
|  | 427 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 428 | int TargetTransformInfo::getCmpSelInstrCost(unsigned Opcode, Type *ValTy, | 
| Jonas Paulsson | fccc7d6 | 2017-04-12 11:49:08 +0000 | [diff] [blame] | 429 | Type *CondTy, const Instruction *I) const { | 
|  | 430 | assert ((I == nullptr || I->getOpcode() == Opcode) && | 
|  | 431 | "Opcode should reflect passed instruction."); | 
|  | 432 | int Cost = TTIImpl->getCmpSelInstrCost(Opcode, ValTy, CondTy, I); | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 433 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 434 | return Cost; | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 435 | } | 
|  | 436 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 437 | int TargetTransformInfo::getVectorInstrCost(unsigned Opcode, Type *Val, | 
|  | 438 | unsigned Index) const { | 
|  | 439 | int Cost = TTIImpl->getVectorInstrCost(Opcode, Val, Index); | 
|  | 440 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 441 | return Cost; | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 442 | } | 
|  | 443 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 444 | int TargetTransformInfo::getMemoryOpCost(unsigned Opcode, Type *Src, | 
|  | 445 | unsigned Alignment, | 
| Jonas Paulsson | fccc7d6 | 2017-04-12 11:49:08 +0000 | [diff] [blame] | 446 | unsigned AddressSpace, | 
|  | 447 | const Instruction *I) const { | 
|  | 448 | assert ((I == nullptr || I->getOpcode() == Opcode) && | 
|  | 449 | "Opcode should reflect passed instruction."); | 
|  | 450 | int Cost = TTIImpl->getMemoryOpCost(Opcode, Src, Alignment, AddressSpace, I); | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 451 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 452 | return Cost; | 
| Elena Demikhovsky | a3232f7 | 2015-01-25 08:44:46 +0000 | [diff] [blame] | 453 | } | 
|  | 454 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 455 | int TargetTransformInfo::getMaskedMemoryOpCost(unsigned Opcode, Type *Src, | 
|  | 456 | unsigned Alignment, | 
|  | 457 | unsigned AddressSpace) const { | 
|  | 458 | int Cost = | 
|  | 459 | TTIImpl->getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace); | 
|  | 460 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 461 | return Cost; | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 462 | } | 
|  | 463 |  | 
| Elena Demikhovsky | 5494698 | 2015-12-28 20:10:59 +0000 | [diff] [blame] | 464 | int TargetTransformInfo::getGatherScatterOpCost(unsigned Opcode, Type *DataTy, | 
|  | 465 | Value *Ptr, bool VariableMask, | 
|  | 466 | unsigned Alignment) const { | 
|  | 467 | int Cost = TTIImpl->getGatherScatterOpCost(Opcode, DataTy, Ptr, VariableMask, | 
|  | 468 | Alignment); | 
|  | 469 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 470 | return Cost; | 
|  | 471 | } | 
|  | 472 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 473 | int TargetTransformInfo::getInterleavedMemoryOpCost( | 
| Hao Liu | 32c0539 | 2015-06-08 06:39:56 +0000 | [diff] [blame] | 474 | unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices, | 
|  | 475 | unsigned Alignment, unsigned AddressSpace) const { | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 476 | int Cost = TTIImpl->getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices, | 
|  | 477 | Alignment, AddressSpace); | 
|  | 478 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 479 | return Cost; | 
| Hao Liu | 32c0539 | 2015-06-08 06:39:56 +0000 | [diff] [blame] | 480 | } | 
|  | 481 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 482 | int TargetTransformInfo::getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, | 
| Jonas Paulsson | a48ea23 | 2017-03-14 06:35:36 +0000 | [diff] [blame] | 483 | ArrayRef<Type *> Tys, FastMathFlags FMF, | 
|  | 484 | unsigned ScalarizationCostPassed) const { | 
|  | 485 | int Cost = TTIImpl->getIntrinsicInstrCost(ID, RetTy, Tys, FMF, | 
|  | 486 | ScalarizationCostPassed); | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 487 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 488 | return Cost; | 
|  | 489 | } | 
|  | 490 |  | 
| Elena Demikhovsky | 5494698 | 2015-12-28 20:10:59 +0000 | [diff] [blame] | 491 | int TargetTransformInfo::getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, | 
| Jonas Paulsson | a48ea23 | 2017-03-14 06:35:36 +0000 | [diff] [blame] | 492 | ArrayRef<Value *> Args, FastMathFlags FMF, unsigned VF) const { | 
|  | 493 | int Cost = TTIImpl->getIntrinsicInstrCost(ID, RetTy, Args, FMF, VF); | 
| Elena Demikhovsky | 5494698 | 2015-12-28 20:10:59 +0000 | [diff] [blame] | 494 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 495 | return Cost; | 
|  | 496 | } | 
|  | 497 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 498 | int TargetTransformInfo::getCallInstrCost(Function *F, Type *RetTy, | 
|  | 499 | ArrayRef<Type *> Tys) const { | 
|  | 500 | int Cost = TTIImpl->getCallInstrCost(F, RetTy, Tys); | 
|  | 501 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 502 | return Cost; | 
| Michael Zolotukhin | 7ed84a8 | 2015-03-17 19:26:23 +0000 | [diff] [blame] | 503 | } | 
|  | 504 |  | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 505 | unsigned TargetTransformInfo::getNumberOfParts(Type *Tp) const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 506 | return TTIImpl->getNumberOfParts(Tp); | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 507 | } | 
|  | 508 |  | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 509 | int TargetTransformInfo::getAddressComputationCost(Type *Tp, | 
| Mohammed Agabaria | 23599ba | 2017-01-05 14:03:41 +0000 | [diff] [blame] | 510 | ScalarEvolution *SE, | 
|  | 511 | const SCEV *Ptr) const { | 
|  | 512 | int Cost = TTIImpl->getAddressComputationCost(Tp, SE, Ptr); | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 513 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 514 | return Cost; | 
| Arnold Schwaighofer | 594fa2d | 2013-02-08 14:50:48 +0000 | [diff] [blame] | 515 | } | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 516 |  | 
| Alexey Bataev | 3e9b3eb | 2017-07-31 14:19:32 +0000 | [diff] [blame] | 517 | int TargetTransformInfo::getArithmeticReductionCost(unsigned Opcode, Type *Ty, | 
|  | 518 | bool IsPairwiseForm) const { | 
|  | 519 | int Cost = TTIImpl->getArithmeticReductionCost(Opcode, Ty, IsPairwiseForm); | 
| Chandler Carruth | 93205eb | 2015-08-05 18:08:10 +0000 | [diff] [blame] | 520 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 521 | return Cost; | 
| Arnold Schwaighofer | cae8735 | 2013-09-17 18:06:50 +0000 | [diff] [blame] | 522 | } | 
|  | 523 |  | 
| Alexey Bataev | 6dd29fc | 2017-09-08 13:49:36 +0000 | [diff] [blame] | 524 | int TargetTransformInfo::getMinMaxReductionCost(Type *Ty, Type *CondTy, | 
|  | 525 | bool IsPairwiseForm, | 
|  | 526 | bool IsUnsigned) const { | 
|  | 527 | int Cost = | 
|  | 528 | TTIImpl->getMinMaxReductionCost(Ty, CondTy, IsPairwiseForm, IsUnsigned); | 
|  | 529 | assert(Cost >= 0 && "TTI should not produce negative costs!"); | 
|  | 530 | return Cost; | 
|  | 531 | } | 
|  | 532 |  | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 533 | unsigned | 
|  | 534 | TargetTransformInfo::getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const { | 
|  | 535 | return TTIImpl->getCostOfKeepingLiveOverCall(Tys); | 
| Chad Rosier | f9327d6 | 2015-01-26 22:51:15 +0000 | [diff] [blame] | 536 | } | 
|  | 537 |  | 
|  | 538 | bool TargetTransformInfo::getTgtMemIntrinsic(IntrinsicInst *Inst, | 
|  | 539 | MemIntrinsicInfo &Info) const { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 540 | return TTIImpl->getTgtMemIntrinsic(Inst, Info); | 
| Chad Rosier | f9327d6 | 2015-01-26 22:51:15 +0000 | [diff] [blame] | 541 | } | 
|  | 542 |  | 
| Anna Thomas | b2a212c | 2017-06-06 16:45:25 +0000 | [diff] [blame] | 543 | unsigned TargetTransformInfo::getAtomicMemIntrinsicMaxElementSize() const { | 
|  | 544 | return TTIImpl->getAtomicMemIntrinsicMaxElementSize(); | 
|  | 545 | } | 
|  | 546 |  | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 547 | Value *TargetTransformInfo::getOrCreateResultFromMemIntrinsic( | 
|  | 548 | IntrinsicInst *Inst, Type *ExpectedType) const { | 
|  | 549 | return TTIImpl->getOrCreateResultFromMemIntrinsic(Inst, ExpectedType); | 
|  | 550 | } | 
|  | 551 |  | 
| Sean Fertile | 9cd1cdf | 2017-07-07 02:00:06 +0000 | [diff] [blame] | 552 | Type *TargetTransformInfo::getMemcpyLoopLoweringType(LLVMContext &Context, | 
|  | 553 | Value *Length, | 
|  | 554 | unsigned SrcAlign, | 
|  | 555 | unsigned DestAlign) const { | 
|  | 556 | return TTIImpl->getMemcpyLoopLoweringType(Context, Length, SrcAlign, | 
|  | 557 | DestAlign); | 
|  | 558 | } | 
|  | 559 |  | 
|  | 560 | void TargetTransformInfo::getMemcpyLoopResidualLoweringType( | 
|  | 561 | SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context, | 
|  | 562 | unsigned RemainingBytes, unsigned SrcAlign, unsigned DestAlign) const { | 
|  | 563 | TTIImpl->getMemcpyLoopResidualLoweringType(OpsOut, Context, RemainingBytes, | 
|  | 564 | SrcAlign, DestAlign); | 
|  | 565 | } | 
|  | 566 |  | 
| Eric Christopher | d566fb1 | 2015-07-29 22:09:48 +0000 | [diff] [blame] | 567 | bool TargetTransformInfo::areInlineCompatible(const Function *Caller, | 
|  | 568 | const Function *Callee) const { | 
|  | 569 | return TTIImpl->areInlineCompatible(Caller, Callee); | 
| Eric Christopher | 4371b13 | 2015-07-02 01:11:47 +0000 | [diff] [blame] | 570 | } | 
|  | 571 |  | 
| Krzysztof Parzyszek | 0b377e0 | 2018-03-26 13:10:09 +0000 | [diff] [blame] | 572 | bool TargetTransformInfo::isIndexedLoadLegal(MemIndexedMode Mode, | 
|  | 573 | Type *Ty) const { | 
|  | 574 | return TTIImpl->isIndexedLoadLegal(Mode, Ty); | 
|  | 575 | } | 
|  | 576 |  | 
|  | 577 | bool TargetTransformInfo::isIndexedStoreLegal(MemIndexedMode Mode, | 
|  | 578 | Type *Ty) const { | 
|  | 579 | return TTIImpl->isIndexedStoreLegal(Mode, Ty); | 
|  | 580 | } | 
|  | 581 |  | 
| Volkan Keles | 1c38681 | 2016-10-03 10:31:34 +0000 | [diff] [blame] | 582 | unsigned TargetTransformInfo::getLoadStoreVecRegBitWidth(unsigned AS) const { | 
|  | 583 | return TTIImpl->getLoadStoreVecRegBitWidth(AS); | 
|  | 584 | } | 
|  | 585 |  | 
|  | 586 | bool TargetTransformInfo::isLegalToVectorizeLoad(LoadInst *LI) const { | 
|  | 587 | return TTIImpl->isLegalToVectorizeLoad(LI); | 
|  | 588 | } | 
|  | 589 |  | 
|  | 590 | bool TargetTransformInfo::isLegalToVectorizeStore(StoreInst *SI) const { | 
|  | 591 | return TTIImpl->isLegalToVectorizeStore(SI); | 
|  | 592 | } | 
|  | 593 |  | 
|  | 594 | bool TargetTransformInfo::isLegalToVectorizeLoadChain( | 
|  | 595 | unsigned ChainSizeInBytes, unsigned Alignment, unsigned AddrSpace) const { | 
|  | 596 | return TTIImpl->isLegalToVectorizeLoadChain(ChainSizeInBytes, Alignment, | 
|  | 597 | AddrSpace); | 
|  | 598 | } | 
|  | 599 |  | 
|  | 600 | bool TargetTransformInfo::isLegalToVectorizeStoreChain( | 
|  | 601 | unsigned ChainSizeInBytes, unsigned Alignment, unsigned AddrSpace) const { | 
|  | 602 | return TTIImpl->isLegalToVectorizeStoreChain(ChainSizeInBytes, Alignment, | 
|  | 603 | AddrSpace); | 
|  | 604 | } | 
|  | 605 |  | 
|  | 606 | unsigned TargetTransformInfo::getLoadVectorFactor(unsigned VF, | 
|  | 607 | unsigned LoadSize, | 
|  | 608 | unsigned ChainSizeInBytes, | 
|  | 609 | VectorType *VecTy) const { | 
|  | 610 | return TTIImpl->getLoadVectorFactor(VF, LoadSize, ChainSizeInBytes, VecTy); | 
|  | 611 | } | 
|  | 612 |  | 
|  | 613 | unsigned TargetTransformInfo::getStoreVectorFactor(unsigned VF, | 
|  | 614 | unsigned StoreSize, | 
|  | 615 | unsigned ChainSizeInBytes, | 
|  | 616 | VectorType *VecTy) const { | 
|  | 617 | return TTIImpl->getStoreVectorFactor(VF, StoreSize, ChainSizeInBytes, VecTy); | 
|  | 618 | } | 
|  | 619 |  | 
| Amara Emerson | cf9daa3 | 2017-05-09 10:43:25 +0000 | [diff] [blame] | 620 | bool TargetTransformInfo::useReductionIntrinsic(unsigned Opcode, | 
|  | 621 | Type *Ty, ReductionFlags Flags) const { | 
|  | 622 | return TTIImpl->useReductionIntrinsic(Opcode, Ty, Flags); | 
|  | 623 | } | 
|  | 624 |  | 
| Amara Emerson | 836b0f4 | 2017-05-10 09:42:49 +0000 | [diff] [blame] | 625 | bool TargetTransformInfo::shouldExpandReduction(const IntrinsicInst *II) const { | 
|  | 626 | return TTIImpl->shouldExpandReduction(II); | 
|  | 627 | } | 
| Amara Emerson | cf9daa3 | 2017-05-09 10:43:25 +0000 | [diff] [blame] | 628 |  | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 629 | int TargetTransformInfo::getInstructionLatency(const Instruction *I) const { | 
|  | 630 | return TTIImpl->getInstructionLatency(I); | 
|  | 631 | } | 
|  | 632 |  | 
|  | 633 | static bool isReverseVectorMask(ArrayRef<int> Mask) { | 
| Simon Pilgrim | 32702cc | 2018-06-14 09:35:00 +0000 | [diff] [blame] | 634 | bool ReverseLHS = true; | 
|  | 635 | bool ReverseRHS = true; | 
|  | 636 | unsigned MaskSize = Mask.size(); | 
|  | 637 |  | 
|  | 638 | for (unsigned i = 0; i < MaskSize && (ReverseLHS || ReverseRHS); ++i) { | 
|  | 639 | if (Mask[i] < 0) | 
|  | 640 | continue; | 
|  | 641 | ReverseLHS &= (Mask[i] == (int)(MaskSize - 1 - i)); | 
|  | 642 | ReverseRHS &= (Mask[i] == (int)(MaskSize + MaskSize - 1 - i)); | 
|  | 643 | } | 
|  | 644 | return ReverseLHS || ReverseRHS; | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 645 | } | 
|  | 646 |  | 
|  | 647 | static bool isSingleSourceVectorMask(ArrayRef<int> Mask) { | 
| Simon Pilgrim | c0d53ab | 2018-06-14 09:48:19 +0000 | [diff] [blame] | 648 | bool ShuffleLHS = false; | 
|  | 649 | bool ShuffleRHS = false; | 
|  | 650 | unsigned MaskSize = Mask.size(); | 
|  | 651 |  | 
|  | 652 | for (unsigned i = 0; i < MaskSize && !(ShuffleLHS && ShuffleRHS); ++i) { | 
|  | 653 | if (Mask[i] < 0) | 
|  | 654 | continue; | 
|  | 655 | if ((unsigned)Mask[i] >= MaskSize) | 
|  | 656 | ShuffleRHS = true; | 
|  | 657 | else | 
|  | 658 | ShuffleLHS = true; | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 659 | } | 
| Simon Pilgrim | c0d53ab | 2018-06-14 09:48:19 +0000 | [diff] [blame] | 660 | return !(ShuffleLHS && ShuffleRHS); | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 661 | } | 
|  | 662 |  | 
|  | 663 | static bool isZeroEltBroadcastVectorMask(ArrayRef<int> Mask) { | 
| Simon Pilgrim | 54a138a | 2018-06-13 16:52:02 +0000 | [diff] [blame] | 664 | bool BroadcastLHS = true; | 
|  | 665 | bool BroadcastRHS = true; | 
|  | 666 | unsigned MaskSize = Mask.size(); | 
|  | 667 |  | 
|  | 668 | for (unsigned i = 0; i < MaskSize && (BroadcastLHS || BroadcastRHS); ++i) { | 
|  | 669 | if (Mask[i] < 0) | 
|  | 670 | continue; | 
|  | 671 | BroadcastLHS &= (Mask[i] == 0); | 
|  | 672 | BroadcastRHS &= (Mask[i] == (int)MaskSize); | 
|  | 673 | } | 
|  | 674 | return BroadcastLHS || BroadcastRHS; | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 675 | } | 
|  | 676 |  | 
| Simon Pilgrim | 0783921 | 2018-06-12 14:47:13 +0000 | [diff] [blame] | 677 | static bool isIdentityVectorMask(ArrayRef<int> Mask) { | 
|  | 678 | bool IdentityLHS = true; | 
|  | 679 | bool IdentityRHS = true; | 
|  | 680 | unsigned MaskSize = Mask.size(); | 
|  | 681 |  | 
|  | 682 | // Example: shufflevector A, B, <0,1,u,3> | 
|  | 683 | // Example: shufflevector A, B, <4,u,6,u> | 
|  | 684 | for (unsigned i = 0; i < MaskSize && (IdentityLHS || IdentityRHS); ++i) { | 
|  | 685 | if (Mask[i] < 0) | 
|  | 686 | continue; | 
| Simon Pilgrim | 51ef8dab | 2018-06-12 15:14:34 +0000 | [diff] [blame] | 687 | IdentityLHS &= (Mask[i] == (int)i); | 
|  | 688 | IdentityRHS &= (Mask[i] == (int)(i + MaskSize)); | 
| Simon Pilgrim | 0783921 | 2018-06-12 14:47:13 +0000 | [diff] [blame] | 689 | } | 
|  | 690 | return IdentityLHS || IdentityRHS; | 
|  | 691 | } | 
|  | 692 |  | 
| Simon Pilgrim | e39fa6c | 2018-06-12 16:12:29 +0000 | [diff] [blame] | 693 | static bool isSelectVectorMask(ArrayRef<int> Mask) { | 
|  | 694 | bool IsSelect = true; | 
|  | 695 | bool FoundLHS = false; | 
|  | 696 | bool FoundRHS = false; | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 697 | unsigned MaskSize = Mask.size(); | 
|  | 698 |  | 
| Simon Pilgrim | e39fa6c | 2018-06-12 16:12:29 +0000 | [diff] [blame] | 699 | // Example: shufflevector A, B, <0,1,6,3> | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 700 | // Example: shufflevector A, B, <4,1,6,3> | 
| Simon Pilgrim | e39fa6c | 2018-06-12 16:12:29 +0000 | [diff] [blame] | 701 | for (unsigned i = 0; i < MaskSize && IsSelect; ++i) { | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 702 | if (Mask[i] < 0) | 
|  | 703 | continue; | 
| Simon Pilgrim | e39fa6c | 2018-06-12 16:12:29 +0000 | [diff] [blame] | 704 | bool IsLHS = (Mask[i] == (int)i); | 
|  | 705 | bool IsRHS = (Mask[i] == (int)(i + MaskSize)); | 
|  | 706 | FoundLHS |= IsLHS; | 
|  | 707 | FoundRHS |= IsRHS; | 
|  | 708 | IsSelect = IsLHS || IsRHS; | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 709 | } | 
| Simon Pilgrim | e39fa6c | 2018-06-12 16:12:29 +0000 | [diff] [blame] | 710 | // If we don't use both vectors this is really an Identity mask. | 
|  | 711 | return IsSelect && FoundLHS && FoundRHS; | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 712 | } | 
|  | 713 |  | 
| Matthew Simpson | b4096eb | 2018-04-26 13:48:33 +0000 | [diff] [blame] | 714 | static bool isTransposeVectorMask(ArrayRef<int> Mask) { | 
|  | 715 | // Transpose vector masks transpose a 2xn matrix. They read corresponding | 
|  | 716 | // even- or odd-numbered vector elements from two n-dimensional source | 
|  | 717 | // vectors and write each result into consecutive elements of an | 
|  | 718 | // n-dimensional destination vector. Two shuffles are necessary to complete | 
|  | 719 | // the transpose, one for the even elements and another for the odd elements. | 
|  | 720 | // This description closely follows how the TRN1 and TRN2 AArch64 | 
|  | 721 | // instructions operate. | 
|  | 722 | // | 
|  | 723 | // For example, a simple 2x2 matrix can be transposed with: | 
|  | 724 | // | 
|  | 725 | //   ; Original matrix | 
|  | 726 | //   m0 = <a, b> | 
|  | 727 | //   m1 = <c, d> | 
|  | 728 | // | 
|  | 729 | //   ; Transposed matrix | 
|  | 730 | //   t0 = <a, c> = shufflevector m0, m1, <0, 2> | 
|  | 731 | //   t1 = <b, d> = shufflevector m0, m1, <1, 3> | 
|  | 732 | // | 
|  | 733 | // For matrices having greater than n columns, the resulting nx2 transposed | 
|  | 734 | // matrix is stored in two result vectors such that one vector contains | 
|  | 735 | // interleaved elements from all the even-numbered rows and the other vector | 
|  | 736 | // contains interleaved elements from all the odd-numbered rows. For example, | 
|  | 737 | // a 2x4 matrix can be transposed with: | 
|  | 738 | // | 
|  | 739 | //   ; Original matrix | 
|  | 740 | //   m0 = <a, b, c, d> | 
|  | 741 | //   m1 = <e, f, g, h> | 
|  | 742 | // | 
|  | 743 | //   ; Transposed matrix | 
|  | 744 | //   t0 = <a, e, c, g> = shufflevector m0, m1 <0, 4, 2, 6> | 
|  | 745 | //   t1 = <b, f, d, h> = shufflevector m0, m1 <1, 5, 3, 7> | 
|  | 746 | // | 
|  | 747 | // The above explanation places limitations on what valid transpose masks can | 
|  | 748 | // look like. These limitations are defined by the checks below. | 
|  | 749 | // | 
|  | 750 | // 1. The number of elements in the mask must be a power of two. | 
|  | 751 | if (!isPowerOf2_32(Mask.size())) | 
|  | 752 | return false; | 
|  | 753 |  | 
|  | 754 | // 2. The first element of the mask must be either a zero (for the | 
|  | 755 | // even-numbered vector elements) or a one (for the odd-numbered vector | 
|  | 756 | // elements). | 
|  | 757 | if (Mask[0] != 0 && Mask[0] != 1) | 
|  | 758 | return false; | 
|  | 759 |  | 
|  | 760 | // 3. The difference between the first two elements must be equal to the | 
|  | 761 | // number of elements in the mask. | 
|  | 762 | if (Mask[1] - Mask[0] != (int)Mask.size()) | 
|  | 763 | return false; | 
|  | 764 |  | 
|  | 765 | // 4. The difference between consecutive even-numbered and odd-numbered | 
|  | 766 | // elements must be equal to two. | 
|  | 767 | for (int I = 2; I < (int)Mask.size(); ++I) | 
|  | 768 | if (Mask[I] - Mask[I - 2] != 2) | 
|  | 769 | return false; | 
|  | 770 |  | 
|  | 771 | return true; | 
|  | 772 | } | 
|  | 773 |  | 
| Simon Pilgrim | 4162d77 | 2018-05-22 10:40:09 +0000 | [diff] [blame] | 774 | TargetTransformInfo::OperandValueKind | 
|  | 775 | getOperandInfo(Value *V, TargetTransformInfo::OperandValueProperties &OpProps) { | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 776 | TargetTransformInfo::OperandValueKind OpInfo = | 
|  | 777 | TargetTransformInfo::OK_AnyValue; | 
| Simon Pilgrim | 4162d77 | 2018-05-22 10:40:09 +0000 | [diff] [blame] | 778 | OpProps = TargetTransformInfo::OP_None; | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 779 |  | 
| Simon Pilgrim | 4162d77 | 2018-05-22 10:40:09 +0000 | [diff] [blame] | 780 | const Value *Splat = getSplatValue(V); | 
|  | 781 |  | 
|  | 782 | // Check for a splat of a constant or for a non uniform vector of constants | 
|  | 783 | // and check if the constant(s) are all powers of two. | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 784 | if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) { | 
|  | 785 | OpInfo = TargetTransformInfo::OK_NonUniformConstantValue; | 
| Simon Pilgrim | 4162d77 | 2018-05-22 10:40:09 +0000 | [diff] [blame] | 786 | if (Splat) { | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 787 | OpInfo = TargetTransformInfo::OK_UniformConstantValue; | 
| Simon Pilgrim | 4162d77 | 2018-05-22 10:40:09 +0000 | [diff] [blame] | 788 | if (auto *CI = dyn_cast<ConstantInt>(Splat)) | 
|  | 789 | if (CI->getValue().isPowerOf2()) | 
|  | 790 | OpProps = TargetTransformInfo::OP_PowerOf2; | 
|  | 791 | } else if (auto *CDS = dyn_cast<ConstantDataSequential>(V)) { | 
|  | 792 | OpProps = TargetTransformInfo::OP_PowerOf2; | 
|  | 793 | for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) { | 
|  | 794 | if (auto *CI = dyn_cast<ConstantInt>(CDS->getElementAsConstant(I))) | 
|  | 795 | if (CI->getValue().isPowerOf2()) | 
|  | 796 | continue; | 
|  | 797 | OpProps = TargetTransformInfo::OP_None; | 
|  | 798 | break; | 
|  | 799 | } | 
|  | 800 | } | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 801 | } | 
|  | 802 |  | 
|  | 803 | // Check for a splat of a uniform value. This is not loop aware, so return | 
|  | 804 | // true only for the obviously uniform cases (argument, globalvalue) | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 805 | if (Splat && (isa<Argument>(Splat) || isa<GlobalValue>(Splat))) | 
|  | 806 | OpInfo = TargetTransformInfo::OK_UniformValue; | 
|  | 807 |  | 
|  | 808 | return OpInfo; | 
|  | 809 | } | 
|  | 810 |  | 
|  | 811 | static bool matchPairwiseShuffleMask(ShuffleVectorInst *SI, bool IsLeft, | 
|  | 812 | unsigned Level) { | 
|  | 813 | // We don't need a shuffle if we just want to have element 0 in position 0 of | 
|  | 814 | // the vector. | 
|  | 815 | if (!SI && Level == 0 && IsLeft) | 
|  | 816 | return true; | 
|  | 817 | else if (!SI) | 
|  | 818 | return false; | 
|  | 819 |  | 
|  | 820 | SmallVector<int, 32> Mask(SI->getType()->getVectorNumElements(), -1); | 
|  | 821 |  | 
|  | 822 | // Build a mask of 0, 2, ... (left) or 1, 3, ... (right) depending on whether | 
|  | 823 | // we look at the left or right side. | 
|  | 824 | for (unsigned i = 0, e = (1 << Level), val = !IsLeft; i != e; ++i, val += 2) | 
|  | 825 | Mask[i] = val; | 
|  | 826 |  | 
|  | 827 | SmallVector<int, 16> ActualMask = SI->getShuffleMask(); | 
|  | 828 | return Mask == ActualMask; | 
|  | 829 | } | 
|  | 830 |  | 
|  | 831 | namespace { | 
|  | 832 | /// Kind of the reduction data. | 
|  | 833 | enum ReductionKind { | 
|  | 834 | RK_None,           /// Not a reduction. | 
|  | 835 | RK_Arithmetic,     /// Binary reduction data. | 
|  | 836 | RK_MinMax,         /// Min/max reduction data. | 
|  | 837 | RK_UnsignedMinMax, /// Unsigned min/max reduction data. | 
|  | 838 | }; | 
|  | 839 | /// Contains opcode + LHS/RHS parts of the reduction operations. | 
|  | 840 | struct ReductionData { | 
|  | 841 | ReductionData() = delete; | 
|  | 842 | ReductionData(ReductionKind Kind, unsigned Opcode, Value *LHS, Value *RHS) | 
|  | 843 | : Opcode(Opcode), LHS(LHS), RHS(RHS), Kind(Kind) { | 
|  | 844 | assert(Kind != RK_None && "expected binary or min/max reduction only."); | 
|  | 845 | } | 
|  | 846 | unsigned Opcode = 0; | 
|  | 847 | Value *LHS = nullptr; | 
|  | 848 | Value *RHS = nullptr; | 
|  | 849 | ReductionKind Kind = RK_None; | 
|  | 850 | bool hasSameData(ReductionData &RD) const { | 
|  | 851 | return Kind == RD.Kind && Opcode == RD.Opcode; | 
|  | 852 | } | 
|  | 853 | }; | 
|  | 854 | } // namespace | 
|  | 855 |  | 
|  | 856 | static Optional<ReductionData> getReductionData(Instruction *I) { | 
|  | 857 | Value *L, *R; | 
|  | 858 | if (m_BinOp(m_Value(L), m_Value(R)).match(I)) | 
|  | 859 | return ReductionData(RK_Arithmetic, I->getOpcode(), L, R); | 
|  | 860 | if (auto *SI = dyn_cast<SelectInst>(I)) { | 
|  | 861 | if (m_SMin(m_Value(L), m_Value(R)).match(SI) || | 
|  | 862 | m_SMax(m_Value(L), m_Value(R)).match(SI) || | 
|  | 863 | m_OrdFMin(m_Value(L), m_Value(R)).match(SI) || | 
|  | 864 | m_OrdFMax(m_Value(L), m_Value(R)).match(SI) || | 
|  | 865 | m_UnordFMin(m_Value(L), m_Value(R)).match(SI) || | 
|  | 866 | m_UnordFMax(m_Value(L), m_Value(R)).match(SI)) { | 
|  | 867 | auto *CI = cast<CmpInst>(SI->getCondition()); | 
|  | 868 | return ReductionData(RK_MinMax, CI->getOpcode(), L, R); | 
|  | 869 | } | 
|  | 870 | if (m_UMin(m_Value(L), m_Value(R)).match(SI) || | 
|  | 871 | m_UMax(m_Value(L), m_Value(R)).match(SI)) { | 
|  | 872 | auto *CI = cast<CmpInst>(SI->getCondition()); | 
|  | 873 | return ReductionData(RK_UnsignedMinMax, CI->getOpcode(), L, R); | 
|  | 874 | } | 
|  | 875 | } | 
|  | 876 | return llvm::None; | 
|  | 877 | } | 
|  | 878 |  | 
|  | 879 | static ReductionKind matchPairwiseReductionAtLevel(Instruction *I, | 
|  | 880 | unsigned Level, | 
|  | 881 | unsigned NumLevels) { | 
|  | 882 | // Match one level of pairwise operations. | 
|  | 883 | // %rdx.shuf.0.0 = shufflevector <4 x float> %rdx, <4 x float> undef, | 
|  | 884 | //       <4 x i32> <i32 0, i32 2 , i32 undef, i32 undef> | 
|  | 885 | // %rdx.shuf.0.1 = shufflevector <4 x float> %rdx, <4 x float> undef, | 
|  | 886 | //       <4 x i32> <i32 1, i32 3, i32 undef, i32 undef> | 
|  | 887 | // %bin.rdx.0 = fadd <4 x float> %rdx.shuf.0.0, %rdx.shuf.0.1 | 
|  | 888 | if (!I) | 
|  | 889 | return RK_None; | 
|  | 890 |  | 
|  | 891 | assert(I->getType()->isVectorTy() && "Expecting a vector type"); | 
|  | 892 |  | 
|  | 893 | Optional<ReductionData> RD = getReductionData(I); | 
|  | 894 | if (!RD) | 
|  | 895 | return RK_None; | 
|  | 896 |  | 
|  | 897 | ShuffleVectorInst *LS = dyn_cast<ShuffleVectorInst>(RD->LHS); | 
|  | 898 | if (!LS && Level) | 
|  | 899 | return RK_None; | 
|  | 900 | ShuffleVectorInst *RS = dyn_cast<ShuffleVectorInst>(RD->RHS); | 
|  | 901 | if (!RS && Level) | 
|  | 902 | return RK_None; | 
|  | 903 |  | 
|  | 904 | // On level 0 we can omit one shufflevector instruction. | 
|  | 905 | if (!Level && !RS && !LS) | 
|  | 906 | return RK_None; | 
|  | 907 |  | 
|  | 908 | // Shuffle inputs must match. | 
|  | 909 | Value *NextLevelOpL = LS ? LS->getOperand(0) : nullptr; | 
|  | 910 | Value *NextLevelOpR = RS ? RS->getOperand(0) : nullptr; | 
|  | 911 | Value *NextLevelOp = nullptr; | 
|  | 912 | if (NextLevelOpR && NextLevelOpL) { | 
|  | 913 | // If we have two shuffles their operands must match. | 
|  | 914 | if (NextLevelOpL != NextLevelOpR) | 
|  | 915 | return RK_None; | 
|  | 916 |  | 
|  | 917 | NextLevelOp = NextLevelOpL; | 
|  | 918 | } else if (Level == 0 && (NextLevelOpR || NextLevelOpL)) { | 
|  | 919 | // On the first level we can omit the shufflevector <0, undef,...>. So the | 
|  | 920 | // input to the other shufflevector <1, undef> must match with one of the | 
|  | 921 | // inputs to the current binary operation. | 
|  | 922 | // Example: | 
|  | 923 | //  %NextLevelOpL = shufflevector %R, <1, undef ...> | 
|  | 924 | //  %BinOp        = fadd          %NextLevelOpL, %R | 
|  | 925 | if (NextLevelOpL && NextLevelOpL != RD->RHS) | 
|  | 926 | return RK_None; | 
|  | 927 | else if (NextLevelOpR && NextLevelOpR != RD->LHS) | 
|  | 928 | return RK_None; | 
|  | 929 |  | 
|  | 930 | NextLevelOp = NextLevelOpL ? RD->RHS : RD->LHS; | 
|  | 931 | } else | 
|  | 932 | return RK_None; | 
|  | 933 |  | 
|  | 934 | // Check that the next levels binary operation exists and matches with the | 
|  | 935 | // current one. | 
|  | 936 | if (Level + 1 != NumLevels) { | 
|  | 937 | Optional<ReductionData> NextLevelRD = | 
|  | 938 | getReductionData(cast<Instruction>(NextLevelOp)); | 
|  | 939 | if (!NextLevelRD || !RD->hasSameData(*NextLevelRD)) | 
|  | 940 | return RK_None; | 
|  | 941 | } | 
|  | 942 |  | 
|  | 943 | // Shuffle mask for pairwise operation must match. | 
|  | 944 | if (matchPairwiseShuffleMask(LS, /*IsLeft=*/true, Level)) { | 
|  | 945 | if (!matchPairwiseShuffleMask(RS, /*IsLeft=*/false, Level)) | 
|  | 946 | return RK_None; | 
|  | 947 | } else if (matchPairwiseShuffleMask(RS, /*IsLeft=*/true, Level)) { | 
|  | 948 | if (!matchPairwiseShuffleMask(LS, /*IsLeft=*/false, Level)) | 
|  | 949 | return RK_None; | 
|  | 950 | } else { | 
|  | 951 | return RK_None; | 
|  | 952 | } | 
|  | 953 |  | 
|  | 954 | if (++Level == NumLevels) | 
|  | 955 | return RD->Kind; | 
|  | 956 |  | 
|  | 957 | // Match next level. | 
|  | 958 | return matchPairwiseReductionAtLevel(cast<Instruction>(NextLevelOp), Level, | 
|  | 959 | NumLevels); | 
|  | 960 | } | 
|  | 961 |  | 
|  | 962 | static ReductionKind matchPairwiseReduction(const ExtractElementInst *ReduxRoot, | 
|  | 963 | unsigned &Opcode, Type *&Ty) { | 
|  | 964 | if (!EnableReduxCost) | 
|  | 965 | return RK_None; | 
|  | 966 |  | 
|  | 967 | // Need to extract the first element. | 
|  | 968 | ConstantInt *CI = dyn_cast<ConstantInt>(ReduxRoot->getOperand(1)); | 
|  | 969 | unsigned Idx = ~0u; | 
|  | 970 | if (CI) | 
|  | 971 | Idx = CI->getZExtValue(); | 
|  | 972 | if (Idx != 0) | 
|  | 973 | return RK_None; | 
|  | 974 |  | 
|  | 975 | auto *RdxStart = dyn_cast<Instruction>(ReduxRoot->getOperand(0)); | 
|  | 976 | if (!RdxStart) | 
|  | 977 | return RK_None; | 
|  | 978 | Optional<ReductionData> RD = getReductionData(RdxStart); | 
|  | 979 | if (!RD) | 
|  | 980 | return RK_None; | 
|  | 981 |  | 
|  | 982 | Type *VecTy = RdxStart->getType(); | 
|  | 983 | unsigned NumVecElems = VecTy->getVectorNumElements(); | 
|  | 984 | if (!isPowerOf2_32(NumVecElems)) | 
|  | 985 | return RK_None; | 
|  | 986 |  | 
|  | 987 | // We look for a sequence of shuffle,shuffle,add triples like the following | 
|  | 988 | // that builds a pairwise reduction tree. | 
|  | 989 | // | 
|  | 990 | //  (X0, X1, X2, X3) | 
|  | 991 | //   (X0 + X1, X2 + X3, undef, undef) | 
|  | 992 | //    ((X0 + X1) + (X2 + X3), undef, undef, undef) | 
|  | 993 | // | 
|  | 994 | // %rdx.shuf.0.0 = shufflevector <4 x float> %rdx, <4 x float> undef, | 
|  | 995 | //       <4 x i32> <i32 0, i32 2 , i32 undef, i32 undef> | 
|  | 996 | // %rdx.shuf.0.1 = shufflevector <4 x float> %rdx, <4 x float> undef, | 
|  | 997 | //       <4 x i32> <i32 1, i32 3, i32 undef, i32 undef> | 
|  | 998 | // %bin.rdx.0 = fadd <4 x float> %rdx.shuf.0.0, %rdx.shuf.0.1 | 
|  | 999 | // %rdx.shuf.1.0 = shufflevector <4 x float> %bin.rdx.0, <4 x float> undef, | 
|  | 1000 | //       <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef> | 
|  | 1001 | // %rdx.shuf.1.1 = shufflevector <4 x float> %bin.rdx.0, <4 x float> undef, | 
|  | 1002 | //       <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> | 
|  | 1003 | // %bin.rdx8 = fadd <4 x float> %rdx.shuf.1.0, %rdx.shuf.1.1 | 
|  | 1004 | // %r = extractelement <4 x float> %bin.rdx8, i32 0 | 
|  | 1005 | if (matchPairwiseReductionAtLevel(RdxStart, 0, Log2_32(NumVecElems)) == | 
|  | 1006 | RK_None) | 
|  | 1007 | return RK_None; | 
|  | 1008 |  | 
|  | 1009 | Opcode = RD->Opcode; | 
|  | 1010 | Ty = VecTy; | 
|  | 1011 |  | 
|  | 1012 | return RD->Kind; | 
|  | 1013 | } | 
|  | 1014 |  | 
|  | 1015 | static std::pair<Value *, ShuffleVectorInst *> | 
|  | 1016 | getShuffleAndOtherOprd(Value *L, Value *R) { | 
|  | 1017 | ShuffleVectorInst *S = nullptr; | 
|  | 1018 |  | 
|  | 1019 | if ((S = dyn_cast<ShuffleVectorInst>(L))) | 
|  | 1020 | return std::make_pair(R, S); | 
|  | 1021 |  | 
|  | 1022 | S = dyn_cast<ShuffleVectorInst>(R); | 
|  | 1023 | return std::make_pair(L, S); | 
|  | 1024 | } | 
|  | 1025 |  | 
|  | 1026 | static ReductionKind | 
|  | 1027 | matchVectorSplittingReduction(const ExtractElementInst *ReduxRoot, | 
|  | 1028 | unsigned &Opcode, Type *&Ty) { | 
|  | 1029 | if (!EnableReduxCost) | 
|  | 1030 | return RK_None; | 
|  | 1031 |  | 
|  | 1032 | // Need to extract the first element. | 
|  | 1033 | ConstantInt *CI = dyn_cast<ConstantInt>(ReduxRoot->getOperand(1)); | 
|  | 1034 | unsigned Idx = ~0u; | 
|  | 1035 | if (CI) | 
|  | 1036 | Idx = CI->getZExtValue(); | 
|  | 1037 | if (Idx != 0) | 
|  | 1038 | return RK_None; | 
|  | 1039 |  | 
|  | 1040 | auto *RdxStart = dyn_cast<Instruction>(ReduxRoot->getOperand(0)); | 
|  | 1041 | if (!RdxStart) | 
|  | 1042 | return RK_None; | 
|  | 1043 | Optional<ReductionData> RD = getReductionData(RdxStart); | 
|  | 1044 | if (!RD) | 
|  | 1045 | return RK_None; | 
|  | 1046 |  | 
|  | 1047 | Type *VecTy = ReduxRoot->getOperand(0)->getType(); | 
|  | 1048 | unsigned NumVecElems = VecTy->getVectorNumElements(); | 
|  | 1049 | if (!isPowerOf2_32(NumVecElems)) | 
|  | 1050 | return RK_None; | 
|  | 1051 |  | 
|  | 1052 | // We look for a sequence of shuffles and adds like the following matching one | 
|  | 1053 | // fadd, shuffle vector pair at a time. | 
|  | 1054 | // | 
|  | 1055 | // %rdx.shuf = shufflevector <4 x float> %rdx, <4 x float> undef, | 
|  | 1056 | //                           <4 x i32> <i32 2, i32 3, i32 undef, i32 undef> | 
|  | 1057 | // %bin.rdx = fadd <4 x float> %rdx, %rdx.shuf | 
|  | 1058 | // %rdx.shuf7 = shufflevector <4 x float> %bin.rdx, <4 x float> undef, | 
|  | 1059 | //                          <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> | 
|  | 1060 | // %bin.rdx8 = fadd <4 x float> %bin.rdx, %rdx.shuf7 | 
|  | 1061 | // %r = extractelement <4 x float> %bin.rdx8, i32 0 | 
|  | 1062 |  | 
|  | 1063 | unsigned MaskStart = 1; | 
|  | 1064 | Instruction *RdxOp = RdxStart; | 
|  | 1065 | SmallVector<int, 32> ShuffleMask(NumVecElems, 0); | 
|  | 1066 | unsigned NumVecElemsRemain = NumVecElems; | 
|  | 1067 | while (NumVecElemsRemain - 1) { | 
|  | 1068 | // Check for the right reduction operation. | 
|  | 1069 | if (!RdxOp) | 
|  | 1070 | return RK_None; | 
|  | 1071 | Optional<ReductionData> RDLevel = getReductionData(RdxOp); | 
|  | 1072 | if (!RDLevel || !RDLevel->hasSameData(*RD)) | 
|  | 1073 | return RK_None; | 
|  | 1074 |  | 
|  | 1075 | Value *NextRdxOp; | 
|  | 1076 | ShuffleVectorInst *Shuffle; | 
|  | 1077 | std::tie(NextRdxOp, Shuffle) = | 
|  | 1078 | getShuffleAndOtherOprd(RDLevel->LHS, RDLevel->RHS); | 
|  | 1079 |  | 
|  | 1080 | // Check the current reduction operation and the shuffle use the same value. | 
|  | 1081 | if (Shuffle == nullptr) | 
|  | 1082 | return RK_None; | 
|  | 1083 | if (Shuffle->getOperand(0) != NextRdxOp) | 
|  | 1084 | return RK_None; | 
|  | 1085 |  | 
|  | 1086 | // Check that shuffle masks matches. | 
|  | 1087 | for (unsigned j = 0; j != MaskStart; ++j) | 
|  | 1088 | ShuffleMask[j] = MaskStart + j; | 
|  | 1089 | // Fill the rest of the mask with -1 for undef. | 
|  | 1090 | std::fill(&ShuffleMask[MaskStart], ShuffleMask.end(), -1); | 
|  | 1091 |  | 
|  | 1092 | SmallVector<int, 16> Mask = Shuffle->getShuffleMask(); | 
|  | 1093 | if (ShuffleMask != Mask) | 
|  | 1094 | return RK_None; | 
|  | 1095 |  | 
|  | 1096 | RdxOp = dyn_cast<Instruction>(NextRdxOp); | 
|  | 1097 | NumVecElemsRemain /= 2; | 
|  | 1098 | MaskStart *= 2; | 
|  | 1099 | } | 
|  | 1100 |  | 
|  | 1101 | Opcode = RD->Opcode; | 
|  | 1102 | Ty = VecTy; | 
|  | 1103 | return RD->Kind; | 
|  | 1104 | } | 
|  | 1105 |  | 
|  | 1106 | int TargetTransformInfo::getInstructionThroughput(const Instruction *I) const { | 
|  | 1107 | switch (I->getOpcode()) { | 
|  | 1108 | case Instruction::GetElementPtr: | 
|  | 1109 | return getUserCost(I); | 
|  | 1110 |  | 
|  | 1111 | case Instruction::Ret: | 
|  | 1112 | case Instruction::PHI: | 
|  | 1113 | case Instruction::Br: { | 
|  | 1114 | return getCFInstrCost(I->getOpcode()); | 
|  | 1115 | } | 
|  | 1116 | case Instruction::Add: | 
|  | 1117 | case Instruction::FAdd: | 
|  | 1118 | case Instruction::Sub: | 
|  | 1119 | case Instruction::FSub: | 
|  | 1120 | case Instruction::Mul: | 
|  | 1121 | case Instruction::FMul: | 
|  | 1122 | case Instruction::UDiv: | 
|  | 1123 | case Instruction::SDiv: | 
|  | 1124 | case Instruction::FDiv: | 
|  | 1125 | case Instruction::URem: | 
|  | 1126 | case Instruction::SRem: | 
|  | 1127 | case Instruction::FRem: | 
|  | 1128 | case Instruction::Shl: | 
|  | 1129 | case Instruction::LShr: | 
|  | 1130 | case Instruction::AShr: | 
|  | 1131 | case Instruction::And: | 
|  | 1132 | case Instruction::Or: | 
|  | 1133 | case Instruction::Xor: { | 
| Simon Pilgrim | 4162d77 | 2018-05-22 10:40:09 +0000 | [diff] [blame] | 1134 | TargetTransformInfo::OperandValueKind Op1VK, Op2VK; | 
|  | 1135 | TargetTransformInfo::OperandValueProperties Op1VP, Op2VP; | 
|  | 1136 | Op1VK = getOperandInfo(I->getOperand(0), Op1VP); | 
|  | 1137 | Op2VK = getOperandInfo(I->getOperand(1), Op2VP); | 
|  | 1138 | SmallVector<const Value *, 2> Operands(I->operand_values()); | 
|  | 1139 | return getArithmeticInstrCost(I->getOpcode(), I->getType(), Op1VK, Op2VK, | 
|  | 1140 | Op1VP, Op2VP, Operands); | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 1141 | } | 
|  | 1142 | case Instruction::Select: { | 
|  | 1143 | const SelectInst *SI = cast<SelectInst>(I); | 
|  | 1144 | Type *CondTy = SI->getCondition()->getType(); | 
|  | 1145 | return getCmpSelInstrCost(I->getOpcode(), I->getType(), CondTy, I); | 
|  | 1146 | } | 
|  | 1147 | case Instruction::ICmp: | 
|  | 1148 | case Instruction::FCmp: { | 
|  | 1149 | Type *ValTy = I->getOperand(0)->getType(); | 
|  | 1150 | return getCmpSelInstrCost(I->getOpcode(), ValTy, I->getType(), I); | 
|  | 1151 | } | 
|  | 1152 | case Instruction::Store: { | 
|  | 1153 | const StoreInst *SI = cast<StoreInst>(I); | 
|  | 1154 | Type *ValTy = SI->getValueOperand()->getType(); | 
|  | 1155 | return getMemoryOpCost(I->getOpcode(), ValTy, | 
|  | 1156 | SI->getAlignment(), | 
|  | 1157 | SI->getPointerAddressSpace(), I); | 
|  | 1158 | } | 
|  | 1159 | case Instruction::Load: { | 
|  | 1160 | const LoadInst *LI = cast<LoadInst>(I); | 
|  | 1161 | return getMemoryOpCost(I->getOpcode(), I->getType(), | 
|  | 1162 | LI->getAlignment(), | 
|  | 1163 | LI->getPointerAddressSpace(), I); | 
|  | 1164 | } | 
|  | 1165 | case Instruction::ZExt: | 
|  | 1166 | case Instruction::SExt: | 
|  | 1167 | case Instruction::FPToUI: | 
|  | 1168 | case Instruction::FPToSI: | 
|  | 1169 | case Instruction::FPExt: | 
|  | 1170 | case Instruction::PtrToInt: | 
|  | 1171 | case Instruction::IntToPtr: | 
|  | 1172 | case Instruction::SIToFP: | 
|  | 1173 | case Instruction::UIToFP: | 
|  | 1174 | case Instruction::Trunc: | 
|  | 1175 | case Instruction::FPTrunc: | 
|  | 1176 | case Instruction::BitCast: | 
|  | 1177 | case Instruction::AddrSpaceCast: { | 
|  | 1178 | Type *SrcTy = I->getOperand(0)->getType(); | 
|  | 1179 | return getCastInstrCost(I->getOpcode(), I->getType(), SrcTy, I); | 
|  | 1180 | } | 
|  | 1181 | case Instruction::ExtractElement: { | 
|  | 1182 | const ExtractElementInst * EEI = cast<ExtractElementInst>(I); | 
|  | 1183 | ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1)); | 
|  | 1184 | unsigned Idx = -1; | 
|  | 1185 | if (CI) | 
|  | 1186 | Idx = CI->getZExtValue(); | 
|  | 1187 |  | 
|  | 1188 | // Try to match a reduction sequence (series of shufflevector and vector | 
|  | 1189 | // adds followed by a extractelement). | 
|  | 1190 | unsigned ReduxOpCode; | 
|  | 1191 | Type *ReduxType; | 
|  | 1192 |  | 
|  | 1193 | switch (matchVectorSplittingReduction(EEI, ReduxOpCode, ReduxType)) { | 
|  | 1194 | case RK_Arithmetic: | 
|  | 1195 | return getArithmeticReductionCost(ReduxOpCode, ReduxType, | 
|  | 1196 | /*IsPairwiseForm=*/false); | 
|  | 1197 | case RK_MinMax: | 
|  | 1198 | return getMinMaxReductionCost( | 
|  | 1199 | ReduxType, CmpInst::makeCmpResultType(ReduxType), | 
|  | 1200 | /*IsPairwiseForm=*/false, /*IsUnsigned=*/false); | 
|  | 1201 | case RK_UnsignedMinMax: | 
|  | 1202 | return getMinMaxReductionCost( | 
|  | 1203 | ReduxType, CmpInst::makeCmpResultType(ReduxType), | 
|  | 1204 | /*IsPairwiseForm=*/false, /*IsUnsigned=*/true); | 
|  | 1205 | case RK_None: | 
|  | 1206 | break; | 
|  | 1207 | } | 
|  | 1208 |  | 
|  | 1209 | switch (matchPairwiseReduction(EEI, ReduxOpCode, ReduxType)) { | 
|  | 1210 | case RK_Arithmetic: | 
|  | 1211 | return getArithmeticReductionCost(ReduxOpCode, ReduxType, | 
|  | 1212 | /*IsPairwiseForm=*/true); | 
|  | 1213 | case RK_MinMax: | 
|  | 1214 | return getMinMaxReductionCost( | 
|  | 1215 | ReduxType, CmpInst::makeCmpResultType(ReduxType), | 
|  | 1216 | /*IsPairwiseForm=*/true, /*IsUnsigned=*/false); | 
|  | 1217 | case RK_UnsignedMinMax: | 
|  | 1218 | return getMinMaxReductionCost( | 
|  | 1219 | ReduxType, CmpInst::makeCmpResultType(ReduxType), | 
|  | 1220 | /*IsPairwiseForm=*/true, /*IsUnsigned=*/true); | 
|  | 1221 | case RK_None: | 
|  | 1222 | break; | 
|  | 1223 | } | 
|  | 1224 |  | 
|  | 1225 | return getVectorInstrCost(I->getOpcode(), | 
|  | 1226 | EEI->getOperand(0)->getType(), Idx); | 
|  | 1227 | } | 
|  | 1228 | case Instruction::InsertElement: { | 
|  | 1229 | const InsertElementInst * IE = cast<InsertElementInst>(I); | 
|  | 1230 | ConstantInt *CI = dyn_cast<ConstantInt>(IE->getOperand(2)); | 
|  | 1231 | unsigned Idx = -1; | 
|  | 1232 | if (CI) | 
|  | 1233 | Idx = CI->getZExtValue(); | 
|  | 1234 | return getVectorInstrCost(I->getOpcode(), | 
|  | 1235 | IE->getType(), Idx); | 
|  | 1236 | } | 
|  | 1237 | case Instruction::ShuffleVector: { | 
|  | 1238 | const ShuffleVectorInst *Shuffle = cast<ShuffleVectorInst>(I); | 
|  | 1239 | Type *VecTypOp0 = Shuffle->getOperand(0)->getType(); | 
|  | 1240 | unsigned NumVecElems = VecTypOp0->getVectorNumElements(); | 
|  | 1241 | SmallVector<int, 16> Mask = Shuffle->getShuffleMask(); | 
|  | 1242 |  | 
|  | 1243 | if (NumVecElems == Mask.size()) { | 
| Simon Pilgrim | 0783921 | 2018-06-12 14:47:13 +0000 | [diff] [blame] | 1244 | if (isIdentityVectorMask(Mask)) | 
|  | 1245 | return 0; | 
|  | 1246 |  | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 1247 | if (isReverseVectorMask(Mask)) | 
| Matthew Simpson | b4096eb | 2018-04-26 13:48:33 +0000 | [diff] [blame] | 1248 | return TTIImpl->getShuffleCost(TargetTransformInfo::SK_Reverse, | 
|  | 1249 | VecTypOp0, 0, nullptr); | 
| Simon Pilgrim | 0783921 | 2018-06-12 14:47:13 +0000 | [diff] [blame] | 1250 |  | 
| Simon Pilgrim | e39fa6c | 2018-06-12 16:12:29 +0000 | [diff] [blame] | 1251 | if (isSelectVectorMask(Mask)) | 
|  | 1252 | return TTIImpl->getShuffleCost(TargetTransformInfo::SK_Select, | 
| Matthew Simpson | b4096eb | 2018-04-26 13:48:33 +0000 | [diff] [blame] | 1253 | VecTypOp0, 0, nullptr); | 
|  | 1254 |  | 
|  | 1255 | if (isTransposeVectorMask(Mask)) | 
|  | 1256 | return TTIImpl->getShuffleCost(TargetTransformInfo::SK_Transpose, | 
|  | 1257 | VecTypOp0, 0, nullptr); | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 1258 |  | 
|  | 1259 | if (isZeroEltBroadcastVectorMask(Mask)) | 
| Matthew Simpson | b4096eb | 2018-04-26 13:48:33 +0000 | [diff] [blame] | 1260 | return TTIImpl->getShuffleCost(TargetTransformInfo::SK_Broadcast, | 
|  | 1261 | VecTypOp0, 0, nullptr); | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 1262 |  | 
|  | 1263 | if (isSingleSourceVectorMask(Mask)) | 
| Matthew Simpson | b4096eb | 2018-04-26 13:48:33 +0000 | [diff] [blame] | 1264 | return TTIImpl->getShuffleCost(TargetTransformInfo::SK_PermuteSingleSrc, | 
|  | 1265 | VecTypOp0, 0, nullptr); | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 1266 |  | 
| Matthew Simpson | b4096eb | 2018-04-26 13:48:33 +0000 | [diff] [blame] | 1267 | return TTIImpl->getShuffleCost(TargetTransformInfo::SK_PermuteTwoSrc, | 
|  | 1268 | VecTypOp0, 0, nullptr); | 
| Guozhi Wei | 62d6414 | 2017-09-08 22:29:17 +0000 | [diff] [blame] | 1269 | } | 
|  | 1270 |  | 
|  | 1271 | return -1; | 
|  | 1272 | } | 
|  | 1273 | case Instruction::Call: | 
|  | 1274 | if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) { | 
|  | 1275 | SmallVector<Value *, 4> Args(II->arg_operands()); | 
|  | 1276 |  | 
|  | 1277 | FastMathFlags FMF; | 
|  | 1278 | if (auto *FPMO = dyn_cast<FPMathOperator>(II)) | 
|  | 1279 | FMF = FPMO->getFastMathFlags(); | 
|  | 1280 |  | 
|  | 1281 | return getIntrinsicInstrCost(II->getIntrinsicID(), II->getType(), | 
|  | 1282 | Args, FMF); | 
|  | 1283 | } | 
|  | 1284 | return -1; | 
|  | 1285 | default: | 
|  | 1286 | // We don't have any information on this instruction. | 
|  | 1287 | return -1; | 
|  | 1288 | } | 
|  | 1289 | } | 
|  | 1290 |  | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 1291 | TargetTransformInfo::Concept::~Concept() {} | 
|  | 1292 |  | 
| Chandler Carruth | e038552 | 2015-02-01 10:11:22 +0000 | [diff] [blame] | 1293 | TargetIRAnalysis::TargetIRAnalysis() : TTICallback(&getDefaultTTI) {} | 
|  | 1294 |  | 
|  | 1295 | TargetIRAnalysis::TargetIRAnalysis( | 
| Eric Christopher | a4e5d3c | 2015-09-16 23:38:13 +0000 | [diff] [blame] | 1296 | std::function<Result(const Function &)> TTICallback) | 
| Benjamin Kramer | 82de7d3 | 2016-05-27 14:27:24 +0000 | [diff] [blame] | 1297 | : TTICallback(std::move(TTICallback)) {} | 
| Chandler Carruth | e038552 | 2015-02-01 10:11:22 +0000 | [diff] [blame] | 1298 |  | 
| Chandler Carruth | 164a2aa6 | 2016-06-17 00:11:01 +0000 | [diff] [blame] | 1299 | TargetIRAnalysis::Result TargetIRAnalysis::run(const Function &F, | 
| Sean Silva | 36e0d01 | 2016-08-09 00:28:15 +0000 | [diff] [blame] | 1300 | FunctionAnalysisManager &) { | 
| Chandler Carruth | e038552 | 2015-02-01 10:11:22 +0000 | [diff] [blame] | 1301 | return TTICallback(F); | 
|  | 1302 | } | 
|  | 1303 |  | 
| Chandler Carruth | dab4eae | 2016-11-23 17:53:26 +0000 | [diff] [blame] | 1304 | AnalysisKey TargetIRAnalysis::Key; | 
| NAKAMURA Takumi | df0cd72 | 2016-02-28 17:17:00 +0000 | [diff] [blame] | 1305 |  | 
| Eric Christopher | a4e5d3c | 2015-09-16 23:38:13 +0000 | [diff] [blame] | 1306 | TargetIRAnalysis::Result TargetIRAnalysis::getDefaultTTI(const Function &F) { | 
| Mehdi Amini | 5010ebf | 2015-07-09 02:08:42 +0000 | [diff] [blame] | 1307 | return Result(F.getParent()->getDataLayout()); | 
| Chandler Carruth | e038552 | 2015-02-01 10:11:22 +0000 | [diff] [blame] | 1308 | } | 
|  | 1309 |  | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 1310 | // Register the basic pass. | 
|  | 1311 | INITIALIZE_PASS(TargetTransformInfoWrapperPass, "tti", | 
|  | 1312 | "Target Transform Information", false, true) | 
|  | 1313 | char TargetTransformInfoWrapperPass::ID = 0; | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 1314 |  | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 1315 | void TargetTransformInfoWrapperPass::anchor() {} | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 1316 |  | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 1317 | TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass() | 
| Chandler Carruth | 5ec2b1d | 2015-02-01 12:26:09 +0000 | [diff] [blame] | 1318 | : ImmutablePass(ID) { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 1319 | initializeTargetTransformInfoWrapperPassPass( | 
|  | 1320 | *PassRegistry::getPassRegistry()); | 
|  | 1321 | } | 
|  | 1322 |  | 
|  | 1323 | TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass( | 
| Chandler Carruth | 5ec2b1d | 2015-02-01 12:26:09 +0000 | [diff] [blame] | 1324 | TargetIRAnalysis TIRA) | 
|  | 1325 | : ImmutablePass(ID), TIRA(std::move(TIRA)) { | 
| Chandler Carruth | 705b185 | 2015-01-31 03:43:40 +0000 | [diff] [blame] | 1326 | initializeTargetTransformInfoWrapperPassPass( | 
|  | 1327 | *PassRegistry::getPassRegistry()); | 
|  | 1328 | } | 
|  | 1329 |  | 
| Eric Christopher | a4e5d3c | 2015-09-16 23:38:13 +0000 | [diff] [blame] | 1330 | TargetTransformInfo &TargetTransformInfoWrapperPass::getTTI(const Function &F) { | 
| Sean Silva | 36e0d01 | 2016-08-09 00:28:15 +0000 | [diff] [blame] | 1331 | FunctionAnalysisManager DummyFAM; | 
| Chandler Carruth | 164a2aa6 | 2016-06-17 00:11:01 +0000 | [diff] [blame] | 1332 | TTI = TIRA.run(F, DummyFAM); | 
| Chandler Carruth | 5ec2b1d | 2015-02-01 12:26:09 +0000 | [diff] [blame] | 1333 | return *TTI; | 
|  | 1334 | } | 
|  | 1335 |  | 
| Chandler Carruth | 93dcdc4 | 2015-01-31 11:17:59 +0000 | [diff] [blame] | 1336 | ImmutablePass * | 
| Chandler Carruth | 5ec2b1d | 2015-02-01 12:26:09 +0000 | [diff] [blame] | 1337 | llvm::createTargetTransformInfoWrapperPass(TargetIRAnalysis TIRA) { | 
|  | 1338 | return new TargetTransformInfoWrapperPass(std::move(TIRA)); | 
| Chandler Carruth | 539edf4 | 2013-01-05 11:43:11 +0000 | [diff] [blame] | 1339 | } |