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