CombinerHelper.h 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===-- llvm/CodeGen/GlobalISel/CombinerHelper.h --------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===--------------------------------------------------------------------===//
  13. /// \file
  14. /// This contains common combine transformations that may be used in a combine
  15. /// pass,or by the target elsewhere.
  16. /// Targets can pick individual opcode transformations from the helper or use
  17. /// tryCombine which invokes all transformations. All of the transformations
  18. /// return true if the MachineInstruction changed and false otherwise.
  19. ///
  20. //===--------------------------------------------------------------------===//
  21. #ifndef LLVM_CODEGEN_GLOBALISEL_COMBINERHELPER_H
  22. #define LLVM_CODEGEN_GLOBALISEL_COMBINERHELPER_H
  23. #include "llvm/ADT/APFloat.h"
  24. #include "llvm/ADT/DenseMap.h"
  25. #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
  26. #include "llvm/CodeGen/LowLevelType.h"
  27. #include "llvm/CodeGen/Register.h"
  28. #include "llvm/Support/Alignment.h"
  29. namespace llvm {
  30. class GISelChangeObserver;
  31. class MachineIRBuilder;
  32. class MachineInstrBuilder;
  33. class MachineRegisterInfo;
  34. class MachineInstr;
  35. class MachineOperand;
  36. class GISelKnownBits;
  37. class MachineDominatorTree;
  38. class LegalizerInfo;
  39. struct LegalityQuery;
  40. class RegisterBank;
  41. class RegisterBankInfo;
  42. class TargetLowering;
  43. class TargetRegisterInfo;
  44. struct PreferredTuple {
  45. LLT Ty; // The result type of the extend.
  46. unsigned ExtendOpcode; // G_ANYEXT/G_SEXT/G_ZEXT
  47. MachineInstr *MI;
  48. };
  49. struct IndexedLoadStoreMatchInfo {
  50. Register Addr;
  51. Register Base;
  52. Register Offset;
  53. bool IsPre;
  54. };
  55. struct PtrAddChain {
  56. int64_t Imm;
  57. Register Base;
  58. const RegisterBank *Bank;
  59. };
  60. struct RegisterImmPair {
  61. Register Reg;
  62. int64_t Imm;
  63. };
  64. struct ShiftOfShiftedLogic {
  65. MachineInstr *Logic;
  66. MachineInstr *Shift2;
  67. Register LogicNonShiftReg;
  68. uint64_t ValSum;
  69. };
  70. using BuildFnTy = std::function<void(MachineIRBuilder &)>;
  71. struct MergeTruncStoresInfo {
  72. SmallVector<GStore *> FoundStores;
  73. GStore *LowestIdxStore = nullptr;
  74. Register WideSrcVal;
  75. bool NeedBSwap = false;
  76. bool NeedRotate = false;
  77. };
  78. using OperandBuildSteps =
  79. SmallVector<std::function<void(MachineInstrBuilder &)>, 4>;
  80. struct InstructionBuildSteps {
  81. unsigned Opcode = 0; /// The opcode for the produced instruction.
  82. OperandBuildSteps OperandFns; /// Operands to be added to the instruction.
  83. InstructionBuildSteps() = default;
  84. InstructionBuildSteps(unsigned Opcode, const OperandBuildSteps &OperandFns)
  85. : Opcode(Opcode), OperandFns(OperandFns) {}
  86. };
  87. struct InstructionStepsMatchInfo {
  88. /// Describes instructions to be built during a combine.
  89. SmallVector<InstructionBuildSteps, 2> InstrsToBuild;
  90. InstructionStepsMatchInfo() = default;
  91. InstructionStepsMatchInfo(
  92. std::initializer_list<InstructionBuildSteps> InstrsToBuild)
  93. : InstrsToBuild(InstrsToBuild) {}
  94. };
  95. class CombinerHelper {
  96. protected:
  97. MachineIRBuilder &Builder;
  98. MachineRegisterInfo &MRI;
  99. GISelChangeObserver &Observer;
  100. GISelKnownBits *KB;
  101. MachineDominatorTree *MDT;
  102. const LegalizerInfo *LI;
  103. const RegisterBankInfo *RBI;
  104. const TargetRegisterInfo *TRI;
  105. public:
  106. CombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B,
  107. GISelKnownBits *KB = nullptr,
  108. MachineDominatorTree *MDT = nullptr,
  109. const LegalizerInfo *LI = nullptr);
  110. GISelKnownBits *getKnownBits() const {
  111. return KB;
  112. }
  113. const TargetLowering &getTargetLowering() const;
  114. /// \return true if the combine is running prior to legalization, or if \p
  115. /// Query is legal on the target.
  116. bool isLegalOrBeforeLegalizer(const LegalityQuery &Query) const;
  117. /// MachineRegisterInfo::replaceRegWith() and inform the observer of the changes
  118. void replaceRegWith(MachineRegisterInfo &MRI, Register FromReg, Register ToReg) const;
  119. /// Replace a single register operand with a new register and inform the
  120. /// observer of the changes.
  121. void replaceRegOpWith(MachineRegisterInfo &MRI, MachineOperand &FromRegOp,
  122. Register ToReg) const;
  123. /// Replace the opcode in instruction with a new opcode and inform the
  124. /// observer of the changes.
  125. void replaceOpcodeWith(MachineInstr &FromMI, unsigned ToOpcode) const;
  126. /// Get the register bank of \p Reg.
  127. /// If Reg has not been assigned a register, a register class,
  128. /// or a register bank, then this returns nullptr.
  129. ///
  130. /// \pre Reg.isValid()
  131. const RegisterBank *getRegBank(Register Reg) const;
  132. /// Set the register bank of \p Reg.
  133. /// Does nothing if the RegBank is null.
  134. /// This is the counterpart to getRegBank.
  135. void setRegBank(Register Reg, const RegisterBank *RegBank);
  136. /// If \p MI is COPY, try to combine it.
  137. /// Returns true if MI changed.
  138. bool tryCombineCopy(MachineInstr &MI);
  139. bool matchCombineCopy(MachineInstr &MI);
  140. void applyCombineCopy(MachineInstr &MI);
  141. /// Returns true if \p DefMI precedes \p UseMI or they are the same
  142. /// instruction. Both must be in the same basic block.
  143. bool isPredecessor(const MachineInstr &DefMI, const MachineInstr &UseMI);
  144. /// Returns true if \p DefMI dominates \p UseMI. By definition an
  145. /// instruction dominates itself.
  146. ///
  147. /// If we haven't been provided with a MachineDominatorTree during
  148. /// construction, this function returns a conservative result that tracks just
  149. /// a single basic block.
  150. bool dominates(const MachineInstr &DefMI, const MachineInstr &UseMI);
  151. /// If \p MI is extend that consumes the result of a load, try to combine it.
  152. /// Returns true if MI changed.
  153. bool tryCombineExtendingLoads(MachineInstr &MI);
  154. bool matchCombineExtendingLoads(MachineInstr &MI, PreferredTuple &MatchInfo);
  155. void applyCombineExtendingLoads(MachineInstr &MI, PreferredTuple &MatchInfo);
  156. /// Match (and (load x), mask) -> zextload x
  157. bool matchCombineLoadWithAndMask(MachineInstr &MI, BuildFnTy &MatchInfo);
  158. /// Combine \p MI into a pre-indexed or post-indexed load/store operation if
  159. /// legal and the surrounding code makes it useful.
  160. bool tryCombineIndexedLoadStore(MachineInstr &MI);
  161. bool matchCombineIndexedLoadStore(MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo);
  162. void applyCombineIndexedLoadStore(MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo);
  163. bool matchSextTruncSextLoad(MachineInstr &MI);
  164. void applySextTruncSextLoad(MachineInstr &MI);
  165. /// Match sext_inreg(load p), imm -> sextload p
  166. bool matchSextInRegOfLoad(MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo);
  167. void applySextInRegOfLoad(MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo);
  168. /// Try to combine G_[SU]DIV and G_[SU]REM into a single G_[SU]DIVREM
  169. /// when their source operands are identical.
  170. bool matchCombineDivRem(MachineInstr &MI, MachineInstr *&OtherMI);
  171. void applyCombineDivRem(MachineInstr &MI, MachineInstr *&OtherMI);
  172. /// If a brcond's true block is not the fallthrough, make it so by inverting
  173. /// the condition and swapping operands.
  174. bool matchOptBrCondByInvertingCond(MachineInstr &MI, MachineInstr *&BrCond);
  175. void applyOptBrCondByInvertingCond(MachineInstr &MI, MachineInstr *&BrCond);
  176. /// If \p MI is G_CONCAT_VECTORS, try to combine it.
  177. /// Returns true if MI changed.
  178. /// Right now, we support:
  179. /// - concat_vector(undef, undef) => undef
  180. /// - concat_vector(build_vector(A, B), build_vector(C, D)) =>
  181. /// build_vector(A, B, C, D)
  182. ///
  183. /// \pre MI.getOpcode() == G_CONCAT_VECTORS.
  184. bool tryCombineConcatVectors(MachineInstr &MI);
  185. /// Check if the G_CONCAT_VECTORS \p MI is undef or if it
  186. /// can be flattened into a build_vector.
  187. /// In the first case \p IsUndef will be true.
  188. /// In the second case \p Ops will contain the operands needed
  189. /// to produce the flattened build_vector.
  190. ///
  191. /// \pre MI.getOpcode() == G_CONCAT_VECTORS.
  192. bool matchCombineConcatVectors(MachineInstr &MI, bool &IsUndef,
  193. SmallVectorImpl<Register> &Ops);
  194. /// Replace \p MI with a flattened build_vector with \p Ops or an
  195. /// implicit_def if IsUndef is true.
  196. void applyCombineConcatVectors(MachineInstr &MI, bool IsUndef,
  197. const ArrayRef<Register> Ops);
  198. /// Try to combine G_SHUFFLE_VECTOR into G_CONCAT_VECTORS.
  199. /// Returns true if MI changed.
  200. ///
  201. /// \pre MI.getOpcode() == G_SHUFFLE_VECTOR.
  202. bool tryCombineShuffleVector(MachineInstr &MI);
  203. /// Check if the G_SHUFFLE_VECTOR \p MI can be replaced by a
  204. /// concat_vectors.
  205. /// \p Ops will contain the operands needed to produce the flattened
  206. /// concat_vectors.
  207. ///
  208. /// \pre MI.getOpcode() == G_SHUFFLE_VECTOR.
  209. bool matchCombineShuffleVector(MachineInstr &MI,
  210. SmallVectorImpl<Register> &Ops);
  211. /// Replace \p MI with a concat_vectors with \p Ops.
  212. void applyCombineShuffleVector(MachineInstr &MI,
  213. const ArrayRef<Register> Ops);
  214. /// Optimize memcpy intrinsics et al, e.g. constant len calls.
  215. /// /p MaxLen if non-zero specifies the max length of a mem libcall to inline.
  216. ///
  217. /// For example (pre-indexed):
  218. ///
  219. /// $addr = G_PTR_ADD $base, $offset
  220. /// [...]
  221. /// $val = G_LOAD $addr
  222. /// [...]
  223. /// $whatever = COPY $addr
  224. ///
  225. /// -->
  226. ///
  227. /// $val, $addr = G_INDEXED_LOAD $base, $offset, 1 (IsPre)
  228. /// [...]
  229. /// $whatever = COPY $addr
  230. ///
  231. /// or (post-indexed):
  232. ///
  233. /// G_STORE $val, $base
  234. /// [...]
  235. /// $addr = G_PTR_ADD $base, $offset
  236. /// [...]
  237. /// $whatever = COPY $addr
  238. ///
  239. /// -->
  240. ///
  241. /// $addr = G_INDEXED_STORE $val, $base, $offset
  242. /// [...]
  243. /// $whatever = COPY $addr
  244. bool tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen = 0);
  245. bool matchPtrAddImmedChain(MachineInstr &MI, PtrAddChain &MatchInfo);
  246. void applyPtrAddImmedChain(MachineInstr &MI, PtrAddChain &MatchInfo);
  247. /// Fold (shift (shift base, x), y) -> (shift base (x+y))
  248. bool matchShiftImmedChain(MachineInstr &MI, RegisterImmPair &MatchInfo);
  249. void applyShiftImmedChain(MachineInstr &MI, RegisterImmPair &MatchInfo);
  250. /// If we have a shift-by-constant of a bitwise logic op that itself has a
  251. /// shift-by-constant operand with identical opcode, we may be able to convert
  252. /// that into 2 independent shifts followed by the logic op.
  253. bool matchShiftOfShiftedLogic(MachineInstr &MI,
  254. ShiftOfShiftedLogic &MatchInfo);
  255. void applyShiftOfShiftedLogic(MachineInstr &MI,
  256. ShiftOfShiftedLogic &MatchInfo);
  257. /// Transform a multiply by a power-of-2 value to a left shift.
  258. bool matchCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal);
  259. void applyCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal);
  260. // Transform a G_SHL with an extended source into a narrower shift if
  261. // possible.
  262. bool matchCombineShlOfExtend(MachineInstr &MI, RegisterImmPair &MatchData);
  263. void applyCombineShlOfExtend(MachineInstr &MI,
  264. const RegisterImmPair &MatchData);
  265. /// Fold away a merge of an unmerge of the corresponding values.
  266. bool matchCombineMergeUnmerge(MachineInstr &MI, Register &MatchInfo);
  267. /// Reduce a shift by a constant to an unmerge and a shift on a half sized
  268. /// type. This will not produce a shift smaller than \p TargetShiftSize.
  269. bool matchCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftSize,
  270. unsigned &ShiftVal);
  271. void applyCombineShiftToUnmerge(MachineInstr &MI, const unsigned &ShiftVal);
  272. bool tryCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftAmount);
  273. /// Transform <ty,...> G_UNMERGE(G_MERGE ty X, Y, Z) -> ty X, Y, Z.
  274. bool
  275. matchCombineUnmergeMergeToPlainValues(MachineInstr &MI,
  276. SmallVectorImpl<Register> &Operands);
  277. void
  278. applyCombineUnmergeMergeToPlainValues(MachineInstr &MI,
  279. SmallVectorImpl<Register> &Operands);
  280. /// Transform G_UNMERGE Constant -> Constant1, Constant2, ...
  281. bool matchCombineUnmergeConstant(MachineInstr &MI,
  282. SmallVectorImpl<APInt> &Csts);
  283. void applyCombineUnmergeConstant(MachineInstr &MI,
  284. SmallVectorImpl<APInt> &Csts);
  285. /// Transform G_UNMERGE G_IMPLICIT_DEF -> G_IMPLICIT_DEF, G_IMPLICIT_DEF, ...
  286. bool
  287. matchCombineUnmergeUndef(MachineInstr &MI,
  288. std::function<void(MachineIRBuilder &)> &MatchInfo);
  289. /// Transform X, Y<dead> = G_UNMERGE Z -> X = G_TRUNC Z.
  290. bool matchCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI);
  291. void applyCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI);
  292. /// Transform X, Y = G_UNMERGE(G_ZEXT(Z)) -> X = G_ZEXT(Z); Y = G_CONSTANT 0
  293. bool matchCombineUnmergeZExtToZExt(MachineInstr &MI);
  294. void applyCombineUnmergeZExtToZExt(MachineInstr &MI);
  295. /// Transform fp_instr(cst) to constant result of the fp operation.
  296. bool matchCombineConstantFoldFpUnary(MachineInstr &MI,
  297. Optional<APFloat> &Cst);
  298. void applyCombineConstantFoldFpUnary(MachineInstr &MI,
  299. Optional<APFloat> &Cst);
  300. /// Transform IntToPtr(PtrToInt(x)) to x if cast is in the same address space.
  301. bool matchCombineI2PToP2I(MachineInstr &MI, Register &Reg);
  302. void applyCombineI2PToP2I(MachineInstr &MI, Register &Reg);
  303. /// Transform PtrToInt(IntToPtr(x)) to x.
  304. bool matchCombineP2IToI2P(MachineInstr &MI, Register &Reg);
  305. void applyCombineP2IToI2P(MachineInstr &MI, Register &Reg);
  306. /// Transform G_ADD (G_PTRTOINT x), y -> G_PTRTOINT (G_PTR_ADD x, y)
  307. /// Transform G_ADD y, (G_PTRTOINT x) -> G_PTRTOINT (G_PTR_ADD x, y)
  308. bool matchCombineAddP2IToPtrAdd(MachineInstr &MI,
  309. std::pair<Register, bool> &PtrRegAndCommute);
  310. void applyCombineAddP2IToPtrAdd(MachineInstr &MI,
  311. std::pair<Register, bool> &PtrRegAndCommute);
  312. // Transform G_PTR_ADD (G_PTRTOINT C1), C2 -> C1 + C2
  313. bool matchCombineConstPtrAddToI2P(MachineInstr &MI, APInt &NewCst);
  314. void applyCombineConstPtrAddToI2P(MachineInstr &MI, APInt &NewCst);
  315. /// Transform anyext(trunc(x)) to x.
  316. bool matchCombineAnyExtTrunc(MachineInstr &MI, Register &Reg);
  317. void applyCombineAnyExtTrunc(MachineInstr &MI, Register &Reg);
  318. /// Transform zext(trunc(x)) to x.
  319. bool matchCombineZextTrunc(MachineInstr &MI, Register &Reg);
  320. /// Transform [asz]ext([asz]ext(x)) to [asz]ext x.
  321. bool matchCombineExtOfExt(MachineInstr &MI,
  322. std::tuple<Register, unsigned> &MatchInfo);
  323. void applyCombineExtOfExt(MachineInstr &MI,
  324. std::tuple<Register, unsigned> &MatchInfo);
  325. /// Transform fneg(fneg(x)) to x.
  326. bool matchCombineFNegOfFNeg(MachineInstr &MI, Register &Reg);
  327. /// Match fabs(fabs(x)) to fabs(x).
  328. bool matchCombineFAbsOfFAbs(MachineInstr &MI, Register &Src);
  329. void applyCombineFAbsOfFAbs(MachineInstr &MI, Register &Src);
  330. /// Transform fabs(fneg(x)) to fabs(x).
  331. bool matchCombineFAbsOfFNeg(MachineInstr &MI, BuildFnTy &MatchInfo);
  332. /// Transform trunc ([asz]ext x) to x or ([asz]ext x) or (trunc x).
  333. bool matchCombineTruncOfExt(MachineInstr &MI,
  334. std::pair<Register, unsigned> &MatchInfo);
  335. void applyCombineTruncOfExt(MachineInstr &MI,
  336. std::pair<Register, unsigned> &MatchInfo);
  337. /// Transform trunc (shl x, K) to shl (trunc x),
  338. /// K => K < VT.getScalarSizeInBits().
  339. bool matchCombineTruncOfShl(MachineInstr &MI,
  340. std::pair<Register, Register> &MatchInfo);
  341. void applyCombineTruncOfShl(MachineInstr &MI,
  342. std::pair<Register, Register> &MatchInfo);
  343. /// Transform G_MUL(x, -1) to G_SUB(0, x)
  344. void applyCombineMulByNegativeOne(MachineInstr &MI);
  345. /// Return true if any explicit use operand on \p MI is defined by a
  346. /// G_IMPLICIT_DEF.
  347. bool matchAnyExplicitUseIsUndef(MachineInstr &MI);
  348. /// Return true if all register explicit use operands on \p MI are defined by
  349. /// a G_IMPLICIT_DEF.
  350. bool matchAllExplicitUsesAreUndef(MachineInstr &MI);
  351. /// Return true if a G_SHUFFLE_VECTOR instruction \p MI has an undef mask.
  352. bool matchUndefShuffleVectorMask(MachineInstr &MI);
  353. /// Return true if a G_STORE instruction \p MI is storing an undef value.
  354. bool matchUndefStore(MachineInstr &MI);
  355. /// Return true if a G_SELECT instruction \p MI has an undef comparison.
  356. bool matchUndefSelectCmp(MachineInstr &MI);
  357. /// Return true if a G_SELECT instruction \p MI has a constant comparison. If
  358. /// true, \p OpIdx will store the operand index of the known selected value.
  359. bool matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx);
  360. /// Replace an instruction with a G_FCONSTANT with value \p C.
  361. bool replaceInstWithFConstant(MachineInstr &MI, double C);
  362. /// Replace an instruction with a G_CONSTANT with value \p C.
  363. bool replaceInstWithConstant(MachineInstr &MI, int64_t C);
  364. /// Replace an instruction with a G_CONSTANT with value \p C.
  365. bool replaceInstWithConstant(MachineInstr &MI, APInt C);
  366. /// Replace an instruction with a G_IMPLICIT_DEF.
  367. bool replaceInstWithUndef(MachineInstr &MI);
  368. /// Delete \p MI and replace all of its uses with its \p OpIdx-th operand.
  369. bool replaceSingleDefInstWithOperand(MachineInstr &MI, unsigned OpIdx);
  370. /// Delete \p MI and replace all of its uses with \p Replacement.
  371. bool replaceSingleDefInstWithReg(MachineInstr &MI, Register Replacement);
  372. /// Return true if \p MOP1 and \p MOP2 are register operands are defined by
  373. /// equivalent instructions.
  374. bool matchEqualDefs(const MachineOperand &MOP1, const MachineOperand &MOP2);
  375. /// Return true if \p MOP is defined by a G_CONSTANT with a value equal to
  376. /// \p C.
  377. bool matchConstantOp(const MachineOperand &MOP, int64_t C);
  378. /// Optimize (cond ? x : x) -> x
  379. bool matchSelectSameVal(MachineInstr &MI);
  380. /// Optimize (x op x) -> x
  381. bool matchBinOpSameVal(MachineInstr &MI);
  382. /// Check if operand \p OpIdx is zero.
  383. bool matchOperandIsZero(MachineInstr &MI, unsigned OpIdx);
  384. /// Check if operand \p OpIdx is undef.
  385. bool matchOperandIsUndef(MachineInstr &MI, unsigned OpIdx);
  386. /// Check if operand \p OpIdx is known to be a power of 2.
  387. bool matchOperandIsKnownToBeAPowerOfTwo(MachineInstr &MI, unsigned OpIdx);
  388. /// Erase \p MI
  389. bool eraseInst(MachineInstr &MI);
  390. /// Return true if MI is a G_ADD which can be simplified to a G_SUB.
  391. bool matchSimplifyAddToSub(MachineInstr &MI,
  392. std::tuple<Register, Register> &MatchInfo);
  393. void applySimplifyAddToSub(MachineInstr &MI,
  394. std::tuple<Register, Register> &MatchInfo);
  395. /// Match (logic_op (op x...), (op y...)) -> (op (logic_op x, y))
  396. bool
  397. matchHoistLogicOpWithSameOpcodeHands(MachineInstr &MI,
  398. InstructionStepsMatchInfo &MatchInfo);
  399. /// Replace \p MI with a series of instructions described in \p MatchInfo.
  400. void applyBuildInstructionSteps(MachineInstr &MI,
  401. InstructionStepsMatchInfo &MatchInfo);
  402. /// Match ashr (shl x, C), C -> sext_inreg (C)
  403. bool matchAshrShlToSextInreg(MachineInstr &MI,
  404. std::tuple<Register, int64_t> &MatchInfo);
  405. void applyAshShlToSextInreg(MachineInstr &MI,
  406. std::tuple<Register, int64_t> &MatchInfo);
  407. /// Fold and(and(x, C1), C2) -> C1&C2 ? and(x, C1&C2) : 0
  408. bool matchOverlappingAnd(MachineInstr &MI,
  409. BuildFnTy &MatchInfo);
  410. /// \return true if \p MI is a G_AND instruction whose operands are x and y
  411. /// where x & y == x or x & y == y. (E.g., one of operands is all-ones value.)
  412. ///
  413. /// \param [in] MI - The G_AND instruction.
  414. /// \param [out] Replacement - A register the G_AND should be replaced with on
  415. /// success.
  416. bool matchRedundantAnd(MachineInstr &MI, Register &Replacement);
  417. /// \return true if \p MI is a G_OR instruction whose operands are x and y
  418. /// where x | y == x or x | y == y. (E.g., one of operands is all-zeros
  419. /// value.)
  420. ///
  421. /// \param [in] MI - The G_OR instruction.
  422. /// \param [out] Replacement - A register the G_OR should be replaced with on
  423. /// success.
  424. bool matchRedundantOr(MachineInstr &MI, Register &Replacement);
  425. /// \return true if \p MI is a G_SEXT_INREG that can be erased.
  426. bool matchRedundantSExtInReg(MachineInstr &MI);
  427. /// Combine inverting a result of a compare into the opposite cond code.
  428. bool matchNotCmp(MachineInstr &MI, SmallVectorImpl<Register> &RegsToNegate);
  429. void applyNotCmp(MachineInstr &MI, SmallVectorImpl<Register> &RegsToNegate);
  430. /// Fold (xor (and x, y), y) -> (and (not x), y)
  431. ///{
  432. bool matchXorOfAndWithSameReg(MachineInstr &MI,
  433. std::pair<Register, Register> &MatchInfo);
  434. void applyXorOfAndWithSameReg(MachineInstr &MI,
  435. std::pair<Register, Register> &MatchInfo);
  436. ///}
  437. /// Combine G_PTR_ADD with nullptr to G_INTTOPTR
  438. bool matchPtrAddZero(MachineInstr &MI);
  439. void applyPtrAddZero(MachineInstr &MI);
  440. /// Combine G_UREM x, (known power of 2) to an add and bitmasking.
  441. void applySimplifyURemByPow2(MachineInstr &MI);
  442. bool matchCombineInsertVecElts(MachineInstr &MI,
  443. SmallVectorImpl<Register> &MatchInfo);
  444. void applyCombineInsertVecElts(MachineInstr &MI,
  445. SmallVectorImpl<Register> &MatchInfo);
  446. /// Match expression trees of the form
  447. ///
  448. /// \code
  449. /// sN *a = ...
  450. /// sM val = a[0] | (a[1] << N) | (a[2] << 2N) | (a[3] << 3N) ...
  451. /// \endcode
  452. ///
  453. /// And check if the tree can be replaced with a M-bit load + possibly a
  454. /// bswap.
  455. bool matchLoadOrCombine(MachineInstr &MI, BuildFnTy &MatchInfo);
  456. bool matchTruncStoreMerge(MachineInstr &MI, MergeTruncStoresInfo &MatchInfo);
  457. void applyTruncStoreMerge(MachineInstr &MI, MergeTruncStoresInfo &MatchInfo);
  458. bool matchExtendThroughPhis(MachineInstr &MI, MachineInstr *&ExtMI);
  459. void applyExtendThroughPhis(MachineInstr &MI, MachineInstr *&ExtMI);
  460. bool matchExtractVecEltBuildVec(MachineInstr &MI, Register &Reg);
  461. void applyExtractVecEltBuildVec(MachineInstr &MI, Register &Reg);
  462. bool matchExtractAllEltsFromBuildVector(
  463. MachineInstr &MI,
  464. SmallVectorImpl<std::pair<Register, MachineInstr *>> &MatchInfo);
  465. void applyExtractAllEltsFromBuildVector(
  466. MachineInstr &MI,
  467. SmallVectorImpl<std::pair<Register, MachineInstr *>> &MatchInfo);
  468. /// Use a function which takes in a MachineIRBuilder to perform a combine.
  469. /// By default, it erases the instruction \p MI from the function.
  470. void applyBuildFn(MachineInstr &MI, BuildFnTy &MatchInfo);
  471. /// Use a function which takes in a MachineIRBuilder to perform a combine.
  472. /// This variant does not erase \p MI after calling the build function.
  473. void applyBuildFnNoErase(MachineInstr &MI, BuildFnTy &MatchInfo);
  474. bool matchOrShiftToFunnelShift(MachineInstr &MI, BuildFnTy &MatchInfo);
  475. bool matchFunnelShiftToRotate(MachineInstr &MI);
  476. void applyFunnelShiftToRotate(MachineInstr &MI);
  477. bool matchRotateOutOfRange(MachineInstr &MI);
  478. void applyRotateOutOfRange(MachineInstr &MI);
  479. /// \returns true if a G_ICMP instruction \p MI can be replaced with a true
  480. /// or false constant based off of KnownBits information.
  481. bool matchICmpToTrueFalseKnownBits(MachineInstr &MI, int64_t &MatchInfo);
  482. /// \returns true if a G_ICMP \p MI can be replaced with its LHS based off of
  483. /// KnownBits information.
  484. bool
  485. matchICmpToLHSKnownBits(MachineInstr &MI,
  486. BuildFnTy &MatchInfo);
  487. /// \returns true if (and (or x, c1), c2) can be replaced with (and x, c2)
  488. bool matchAndOrDisjointMask(MachineInstr &MI, BuildFnTy &MatchInfo);
  489. bool matchBitfieldExtractFromSExtInReg(MachineInstr &MI,
  490. BuildFnTy &MatchInfo);
  491. /// Match: and (lshr x, cst), mask -> ubfx x, cst, width
  492. bool matchBitfieldExtractFromAnd(MachineInstr &MI, BuildFnTy &MatchInfo);
  493. /// Match: shr (shl x, n), k -> sbfx/ubfx x, pos, width
  494. bool matchBitfieldExtractFromShr(MachineInstr &MI, BuildFnTy &MatchInfo);
  495. /// Match: shr (and x, n), k -> ubfx x, pos, width
  496. bool matchBitfieldExtractFromShrAnd(MachineInstr &MI, BuildFnTy &MatchInfo);
  497. // Helpers for reassociation:
  498. bool matchReassocConstantInnerRHS(GPtrAdd &MI, MachineInstr *RHS,
  499. BuildFnTy &MatchInfo);
  500. bool matchReassocFoldConstantsInSubTree(GPtrAdd &MI, MachineInstr *LHS,
  501. MachineInstr *RHS,
  502. BuildFnTy &MatchInfo);
  503. bool matchReassocConstantInnerLHS(GPtrAdd &MI, MachineInstr *LHS,
  504. MachineInstr *RHS, BuildFnTy &MatchInfo);
  505. /// Reassociate pointer calculations with G_ADD involved, to allow better
  506. /// addressing mode usage.
  507. bool matchReassocPtrAdd(MachineInstr &MI, BuildFnTy &MatchInfo);
  508. /// Do constant folding when opportunities are exposed after MIR building.
  509. bool matchConstantFold(MachineInstr &MI, APInt &MatchInfo);
  510. /// \returns true if it is possible to narrow the width of a scalar binop
  511. /// feeding a G_AND instruction \p MI.
  512. bool matchNarrowBinopFeedingAnd(MachineInstr &MI, BuildFnTy &MatchInfo);
  513. /// Given an G_UDIV \p MI expressing a divide by constant, return an
  514. /// expression that implements it by multiplying by a magic number.
  515. /// Ref: "Hacker's Delight" or "The PowerPC Compiler Writer's Guide".
  516. MachineInstr *buildUDivUsingMul(MachineInstr &MI);
  517. /// Combine G_UDIV by constant into a multiply by magic constant.
  518. bool matchUDivByConst(MachineInstr &MI);
  519. void applyUDivByConst(MachineInstr &MI);
  520. // G_UMULH x, (1 << c)) -> x >> (bitwidth - c)
  521. bool matchUMulHToLShr(MachineInstr &MI);
  522. void applyUMulHToLShr(MachineInstr &MI);
  523. /// Try to transform \p MI by using all of the above
  524. /// combine functions. Returns true if changed.
  525. bool tryCombine(MachineInstr &MI);
  526. /// Emit loads and stores that perform the given memcpy.
  527. /// Assumes \p MI is a G_MEMCPY_INLINE
  528. /// TODO: implement dynamically sized inline memcpy,
  529. /// and rename: s/bool tryEmit/void emit/
  530. bool tryEmitMemcpyInline(MachineInstr &MI);
  531. /// Match:
  532. /// (G_UMULO x, 2) -> (G_UADDO x, x)
  533. /// (G_SMULO x, 2) -> (G_SADDO x, x)
  534. bool matchMulOBy2(MachineInstr &MI, BuildFnTy &MatchInfo);
  535. /// Transform (fadd x, fneg(y)) -> (fsub x, y)
  536. /// (fadd fneg(x), y) -> (fsub y, x)
  537. /// (fsub x, fneg(y)) -> (fadd x, y)
  538. /// (fmul fneg(x), fneg(y)) -> (fmul x, y)
  539. /// (fdiv fneg(x), fneg(y)) -> (fdiv x, y)
  540. /// (fmad fneg(x), fneg(y), z) -> (fmad x, y, z)
  541. /// (fma fneg(x), fneg(y), z) -> (fma x, y, z)
  542. bool matchRedundantNegOperands(MachineInstr &MI, BuildFnTy &MatchInfo);
  543. bool canCombineFMadOrFMA(MachineInstr &MI, bool &AllowFusionGlobally,
  544. bool &HasFMAD, bool &Aggressive,
  545. bool CanReassociate = false);
  546. /// Transform (fadd (fmul x, y), z) -> (fma x, y, z)
  547. /// (fadd (fmul x, y), z) -> (fmad x, y, z)
  548. bool matchCombineFAddFMulToFMadOrFMA(MachineInstr &MI, BuildFnTy &MatchInfo);
  549. /// Transform (fadd (fpext (fmul x, y)), z) -> (fma (fpext x), (fpext y), z)
  550. /// (fadd (fpext (fmul x, y)), z) -> (fmad (fpext x), (fpext y), z)
  551. bool matchCombineFAddFpExtFMulToFMadOrFMA(MachineInstr &MI,
  552. BuildFnTy &MatchInfo);
  553. /// Transform (fadd (fma x, y, (fmul u, v)), z) -> (fma x, y, (fma u, v, z))
  554. /// (fadd (fmad x, y, (fmul u, v)), z) -> (fmad x, y, (fmad u, v, z))
  555. bool matchCombineFAddFMAFMulToFMadOrFMA(MachineInstr &MI,
  556. BuildFnTy &MatchInfo);
  557. // Transform (fadd (fma x, y, (fpext (fmul u, v))), z)
  558. // -> (fma x, y, (fma (fpext u), (fpext v), z))
  559. // (fadd (fmad x, y, (fpext (fmul u, v))), z)
  560. // -> (fmad x, y, (fmad (fpext u), (fpext v), z))
  561. bool matchCombineFAddFpExtFMulToFMadOrFMAAggressive(MachineInstr &MI,
  562. BuildFnTy &MatchInfo);
  563. /// Transform (fsub (fmul x, y), z) -> (fma x, y, -z)
  564. /// (fsub (fmul x, y), z) -> (fmad x, y, -z)
  565. bool matchCombineFSubFMulToFMadOrFMA(MachineInstr &MI, BuildFnTy &MatchInfo);
  566. /// Transform (fsub (fneg (fmul, x, y)), z) -> (fma (fneg x), y, (fneg z))
  567. /// (fsub (fneg (fmul, x, y)), z) -> (fmad (fneg x), y, (fneg z))
  568. bool matchCombineFSubFNegFMulToFMadOrFMA(MachineInstr &MI,
  569. BuildFnTy &MatchInfo);
  570. /// Transform (fsub (fpext (fmul x, y)), z)
  571. /// -> (fma (fpext x), (fpext y), (fneg z))
  572. /// (fsub (fpext (fmul x, y)), z)
  573. /// -> (fmad (fpext x), (fpext y), (fneg z))
  574. bool matchCombineFSubFpExtFMulToFMadOrFMA(MachineInstr &MI,
  575. BuildFnTy &MatchInfo);
  576. /// Transform (fsub (fpext (fneg (fmul x, y))), z)
  577. /// -> (fneg (fma (fpext x), (fpext y), z))
  578. /// (fsub (fpext (fneg (fmul x, y))), z)
  579. /// -> (fneg (fmad (fpext x), (fpext y), z))
  580. bool matchCombineFSubFpExtFNegFMulToFMadOrFMA(MachineInstr &MI,
  581. BuildFnTy &MatchInfo);
  582. private:
  583. /// Given a non-indexed load or store instruction \p MI, find an offset that
  584. /// can be usefully and legally folded into it as a post-indexing operation.
  585. ///
  586. /// \returns true if a candidate is found.
  587. bool findPostIndexCandidate(MachineInstr &MI, Register &Addr, Register &Base,
  588. Register &Offset);
  589. /// Given a non-indexed load or store instruction \p MI, find an offset that
  590. /// can be usefully and legally folded into it as a pre-indexing operation.
  591. ///
  592. /// \returns true if a candidate is found.
  593. bool findPreIndexCandidate(MachineInstr &MI, Register &Addr, Register &Base,
  594. Register &Offset);
  595. /// Helper function for matchLoadOrCombine. Searches for Registers
  596. /// which may have been produced by a load instruction + some arithmetic.
  597. ///
  598. /// \param [in] Root - The search root.
  599. ///
  600. /// \returns The Registers found during the search.
  601. Optional<SmallVector<Register, 8>>
  602. findCandidatesForLoadOrCombine(const MachineInstr *Root) const;
  603. /// Helper function for matchLoadOrCombine.
  604. ///
  605. /// Checks if every register in \p RegsToVisit is defined by a load
  606. /// instruction + some arithmetic.
  607. ///
  608. /// \param [out] MemOffset2Idx - Maps the byte positions each load ends up
  609. /// at to the index of the load.
  610. /// \param [in] MemSizeInBits - The number of bits each load should produce.
  611. ///
  612. /// \returns On success, a 3-tuple containing lowest-index load found, the
  613. /// lowest index, and the last load in the sequence.
  614. Optional<std::tuple<GZExtLoad *, int64_t, GZExtLoad *>>
  615. findLoadOffsetsForLoadOrCombine(
  616. SmallDenseMap<int64_t, int64_t, 8> &MemOffset2Idx,
  617. const SmallVector<Register, 8> &RegsToVisit,
  618. const unsigned MemSizeInBits);
  619. /// Examines the G_PTR_ADD instruction \p PtrAdd and determines if performing
  620. /// a re-association of its operands would break an existing legal addressing
  621. /// mode that the address computation currently represents.
  622. bool reassociationCanBreakAddressingModePattern(MachineInstr &PtrAdd);
  623. };
  624. } // namespace llvm
  625. #endif
  626. #ifdef __GNUC__
  627. #pragma GCC diagnostic pop
  628. #endif