Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h
Line
Count
Source
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
3.37M
  void profileDstOps(ArrayRef<DstOp> Ops, GISelInstProfileBuilder &B) const {
59
3.37M
    for (const DstOp &Op : Ops)
60
3.37M
      profileDstOp(Op, B);
61
3.37M
  }
62
63
  void profileSrcOp(const SrcOp &Op, GISelInstProfileBuilder &B) const;
64
65
3.37M
  void profileSrcOps(ArrayRef<SrcOp> Ops, GISelInstProfileBuilder &B) const {
66
3.37M
    for (const SrcOp &Op : Ops)
67
4.46M
      profileSrcOp(Op, B);
68
3.37M
  }
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