]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h
Vendor import of llvm trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / include / llvm / CodeGen / GlobalISel / ConstantFoldingMIRBuilder.h
1 //===-- llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.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 does trivial
11 /// constant folding.
12 //===----------------------------------------------------------------------===//
13 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
14 #include "llvm/CodeGen/GlobalISel/Utils.h"
15
16 namespace llvm {
17
18 /// An MIRBuilder which does trivial constant folding of binary ops.
19 /// Calls to buildInstr will also try to constant fold binary ops.
20 class ConstantFoldingMIRBuilder : public MachineIRBuilder {
21 public:
22   // Pull in base class constructors.
23   using MachineIRBuilder::MachineIRBuilder;
24
25   virtual ~ConstantFoldingMIRBuilder() = default;
26
27   // Try to provide an overload for buildInstr for binary ops in order to
28   // constant fold.
29   MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
30                                  ArrayRef<SrcOp> SrcOps,
31                                  Optional<unsigned> Flags = None) override {
32     switch (Opc) {
33     default:
34       break;
35     case TargetOpcode::G_ADD:
36     case TargetOpcode::G_AND:
37     case TargetOpcode::G_ASHR:
38     case TargetOpcode::G_LSHR:
39     case TargetOpcode::G_MUL:
40     case TargetOpcode::G_OR:
41     case TargetOpcode::G_SHL:
42     case TargetOpcode::G_SUB:
43     case TargetOpcode::G_XOR:
44     case TargetOpcode::G_UDIV:
45     case TargetOpcode::G_SDIV:
46     case TargetOpcode::G_UREM:
47     case TargetOpcode::G_SREM: {
48       assert(DstOps.size() == 1 && "Invalid dst ops");
49       assert(SrcOps.size() == 2 && "Invalid src ops");
50       const DstOp &Dst = DstOps[0];
51       const SrcOp &Src0 = SrcOps[0];
52       const SrcOp &Src1 = SrcOps[1];
53       if (auto MaybeCst =
54               ConstantFoldBinOp(Opc, Src0.getReg(), Src1.getReg(), *getMRI()))
55         return buildConstant(Dst, MaybeCst->getSExtValue());
56       break;
57     }
58     }
59     return MachineIRBuilder::buildInstr(Opc, DstOps, SrcOps);
60   }
61 };
62 } // namespace llvm