LLVM  8.0.1
CSEMIRBuilder.h
Go to the documentation of this file.
1 //===-- llvm/CodeGen/GlobalISel/CSEMIRBuilder.h --*- C++ -*-==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// This file implements a version of MachineIRBuilder which CSEs insts within
11 /// a MachineBasicBlock.
12 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CODEGEN_GLOBALISEL_CSEMIRBUILDER_H
14 #define LLVM_CODEGEN_GLOBALISEL_CSEMIRBUILDER_H
15 
18 
19 namespace llvm {
20 
21 /// Defines a builder that does CSE of MachineInstructions using GISelCSEInfo.
22 /// Eg usage.
23 ///
24 ///
25 /// GISelCSEInfo *Info =
26 /// &getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEInfo(); CSEMIRBuilder
27 /// CB(Builder.getState()); CB.setCSEInfo(Info); auto A = CB.buildConstant(s32,
28 /// 42); auto B = CB.buildConstant(s32, 42); assert(A == B); unsigned CReg =
29 /// MRI.createGenericVirtualRegister(s32); auto C = CB.buildConstant(CReg, 42);
30 /// assert(C->getOpcode() == TargetOpcode::COPY);
31 /// Explicitly passing in a register would materialize a copy if possible.
32 /// CSEMIRBuilder also does trivial constant folding for binary ops.
34 
35  /// Returns true if A dominates B (within the same basic block).
36  /// Both iterators must be in the same basic block.
37  //
38  // TODO: Another approach for checking dominance is having two iterators and
39  // making them go towards each other until they meet or reach begin/end. Which
40  // approach is better? Should this even change dynamically? For G_CONSTANTS
41  // most of which will be at the top of the BB, the top down approach would be
42  // a better choice. Does IRTranslator placing constants at the beginning still
43  // make sense? Should this change based on Opcode?
44  bool dominates(MachineBasicBlock::const_iterator A,
46 
47  /// For given ID, find a machineinstr in the CSE Map. If found, check if it
48  /// dominates the current insertion point and if not, move it just before the
49  /// current insertion point and return it. If not found, return Null
50  /// MachineInstrBuilder.
51  MachineInstrBuilder getDominatingInstrForID(FoldingSetNodeID &ID,
52  void *&NodeInsertPos);
53  /// Simple check if we can CSE (we have the CSEInfo) or if this Opcode is
54  /// safe to CSE.
55  bool canPerformCSEForOpc(unsigned Opc) const;
56 
57  void profileDstOp(const DstOp &Op, GISelInstProfileBuilder &B) const;
58 
59  void profileDstOps(ArrayRef<DstOp> Ops, GISelInstProfileBuilder &B) const {
60  for (const DstOp &Op : Ops)
61  profileDstOp(Op, B);
62  }
63 
64  void profileSrcOp(const SrcOp &Op, GISelInstProfileBuilder &B) const;
65 
66  void profileSrcOps(ArrayRef<SrcOp> Ops, GISelInstProfileBuilder &B) const {
67  for (const SrcOp &Op : Ops)
68  profileSrcOp(Op, B);
69  }
70 
71  void profileMBBOpcode(GISelInstProfileBuilder &B, unsigned Opc) const;
72 
73  void profileEverything(unsigned Opc, ArrayRef<DstOp> DstOps,
74  ArrayRef<SrcOp> SrcOps, Optional<unsigned> Flags,
75  GISelInstProfileBuilder &B) const;
76 
77  // Takes a MachineInstrBuilder and inserts it into the CSEMap using the
78  // NodeInsertPos.
79  MachineInstrBuilder memoizeMI(MachineInstrBuilder MIB, void *NodeInsertPos);
80 
81  // If we have can CSE an instruction, but still need to materialize to a VReg,
82  // we emit a copy from the CSE'd inst to the VReg.
83  MachineInstrBuilder generateCopiesIfRequired(ArrayRef<DstOp> DstOps,
84  MachineInstrBuilder &MIB);
85 
86  // If we have can CSE an instruction, but still need to materialize to a VReg,
87  // check if we can generate copies. It's not possible to return a single MIB,
88  // while emitting copies to multiple vregs.
89  bool checkCopyToDefsPossible(ArrayRef<DstOp> DstOps);
90 
91 public:
92  // Pull in base class constructors.
94  // Unhide buildInstr
95  MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
96  ArrayRef<SrcOp> SrcOps,
97  Optional<unsigned> Flag = None) override;
98  // Bring in the other overload from the base class.
100 
102  const ConstantInt &Val) override;
103 
104  // Bring in the other overload from the base class.
107  const ConstantFP &Val) override;
108 };
109 } // namespace llvm
110 #endif
MachineIRBuilder()=default
Some constructors for easy use.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
This class represents lattice values for constants.
Definition: AllocatorList.h:24
MachineInstrBuilder buildFConstant(const DstOp &Res, const ConstantFP &Val) override
Build and insert Res = G_FCONSTANT Val.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:118
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
Definition: FoldingSet.h:306
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:264
Helper class to build MachineInstr.
This is the shared class of boolean and integer constants.
Definition: Constants.h:84
virtual MachineInstrBuilder buildFConstant(const DstOp &Res, const ConstantFP &Val)
Build and insert Res = G_FCONSTANT Val.
This file declares the MachineIRBuilder class.
Defines a builder that does CSE of MachineInstructions using GISelCSEInfo.
Definition: CSEMIRBuilder.h:33
MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val) override
Build and insert Res = G_CONSTANT Val.
MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef< DstOp > DstOps, ArrayRef< SrcOp > SrcOps, Optional< unsigned > Flag=None) override