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 case TargetOpcode::G_SEXT_INREG: { 58 assert(DstOps.size() == 1 && "Invalid dst ops"); 59 assert(SrcOps.size() == 2 && "Invalid src ops"); 60 const DstOp &Dst = DstOps[0]; 61 const SrcOp &Src0 = SrcOps[0]; 62 const SrcOp &Src1 = SrcOps[1]; 63 if (auto MaybeCst = 64 ConstantFoldExtOp(Opc, Src0.getReg(), Src1.getImm(), *getMRI())) 65 return buildConstant(Dst, MaybeCst->getSExtValue()); 66 break; 67 } 68 } 69 return MachineIRBuilder::buildInstr(Opc, DstOps, SrcOps); 70 } 71 }; 72 } // namespace llvm 73