]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / CodeGen / GlobalISel / CSEMIRBuilder.h
1 //===-- llvm/CodeGen/GlobalISel/CSEMIRBuilder.h  --*- C++ -*-==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements a version of MachineIRBuilder which CSEs insts within
10 /// a MachineBasicBlock.
11 //===----------------------------------------------------------------------===//
12 #ifndef LLVM_CODEGEN_GLOBALISEL_CSEMIRBUILDER_H
13 #define LLVM_CODEGEN_GLOBALISEL_CSEMIRBUILDER_H
14
15 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
16 #include "llvm/CodeGen/GlobalISel/Utils.h"
17
18 namespace llvm {
19
20 /// Defines a builder that does CSE of MachineInstructions using GISelCSEInfo.
21 /// Eg usage.
22 ///
23 ///
24 /// GISelCSEInfo *Info =
25 /// &getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEInfo(); CSEMIRBuilder
26 /// CB(Builder.getState()); CB.setCSEInfo(Info); auto A = CB.buildConstant(s32,
27 /// 42); auto B = CB.buildConstant(s32, 42); assert(A == B); unsigned CReg =
28 /// MRI.createGenericVirtualRegister(s32); auto C = CB.buildConstant(CReg, 42);
29 /// assert(C->getOpcode() == TargetOpcode::COPY);
30 /// Explicitly passing in a register would materialize a copy if possible.
31 /// CSEMIRBuilder also does trivial constant folding for binary ops.
32 class CSEMIRBuilder : public MachineIRBuilder {
33
34   /// Returns true if A dominates B (within the same basic block).
35   /// Both iterators must be in the same basic block.
36   //
37   // TODO: Another approach for checking dominance is having two iterators and
38   // making them go towards each other until they meet or reach begin/end. Which
39   // approach is better? Should this even change dynamically? For G_CONSTANTS
40   // most of which will be at the top of the BB, the top down approach would be
41   // a better choice. Does IRTranslator placing constants at the beginning still
42   // make sense? Should this change based on Opcode?
43   bool dominates(MachineBasicBlock::const_iterator A,
44                  MachineBasicBlock::const_iterator B) const;
45
46   /// For given ID, find a machineinstr in the CSE Map. If found, check if it
47   /// dominates the current insertion point and if not, move it just before the
48   /// current insertion point and return it. If not found, return Null
49   /// MachineInstrBuilder.
50   MachineInstrBuilder getDominatingInstrForID(FoldingSetNodeID &ID,
51                                               void *&NodeInsertPos);
52   /// Simple check if we can CSE (we have the CSEInfo) or if this Opcode is
53   /// safe to CSE.
54   bool canPerformCSEForOpc(unsigned Opc) const;
55
56   void profileDstOp(const DstOp &Op, GISelInstProfileBuilder &B) const;
57
58   void profileDstOps(ArrayRef<DstOp> Ops, GISelInstProfileBuilder &B) const {
59     for (const DstOp &Op : Ops)
60       profileDstOp(Op, B);
61   }
62
63   void profileSrcOp(const SrcOp &Op, GISelInstProfileBuilder &B) const;
64
65   void profileSrcOps(ArrayRef<SrcOp> Ops, GISelInstProfileBuilder &B) const {
66     for (const SrcOp &Op : Ops)
67       profileSrcOp(Op, B);
68   }
69
70   void profileMBBOpcode(GISelInstProfileBuilder &B, unsigned Opc) const;
71
72   void profileEverything(unsigned Opc, ArrayRef<DstOp> DstOps,
73                          ArrayRef<SrcOp> SrcOps, Optional<unsigned> Flags,
74                          GISelInstProfileBuilder &B) const;
75
76   // Takes a MachineInstrBuilder and inserts it into the CSEMap using the
77   // NodeInsertPos.
78   MachineInstrBuilder memoizeMI(MachineInstrBuilder MIB, void *NodeInsertPos);
79
80   // If we have can CSE an instruction, but still need to materialize to a VReg,
81   // we emit a copy from the CSE'd inst to the VReg.
82   MachineInstrBuilder generateCopiesIfRequired(ArrayRef<DstOp> DstOps,
83                                                MachineInstrBuilder &MIB);
84
85   // If we have can CSE an instruction, but still need to materialize to a VReg,
86   // check if we can generate copies. It's not possible to return a single MIB,
87   // while emitting copies to multiple vregs.
88   bool checkCopyToDefsPossible(ArrayRef<DstOp> DstOps);
89
90 public:
91   // Pull in base class constructors.
92   using MachineIRBuilder::MachineIRBuilder;
93   // Unhide buildInstr
94   MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
95                                  ArrayRef<SrcOp> SrcOps,
96                                  Optional<unsigned> Flag = None) override;
97   // Bring in the other overload from the base class.
98   using MachineIRBuilder::buildConstant;
99
100   MachineInstrBuilder buildConstant(const DstOp &Res,
101                                     const ConstantInt &Val) override;
102
103   // Bring in the other overload from the base class.
104   using MachineIRBuilder::buildFConstant;
105   MachineInstrBuilder buildFConstant(const DstOp &Res,
106                                      const ConstantFP &Val) override;
107 };
108 } // namespace llvm
109 #endif