1a580b014SDimitry Andric //===- llvm/CodeGen/GlobalISel/InstructionSelector.cpp --------------------===//
2d88c1a5aSDimitry Andric //
3d88c1a5aSDimitry Andric //                     The LLVM Compiler Infrastructure
4d88c1a5aSDimitry Andric //
5d88c1a5aSDimitry Andric // This file is distributed under the University of Illinois Open Source
6d88c1a5aSDimitry Andric // License. See LICENSE.TXT for details.
7d88c1a5aSDimitry Andric //
8d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===//
92cab237bSDimitry Andric //
10d88c1a5aSDimitry Andric /// \file
11d88c1a5aSDimitry Andric /// This file implements the InstructionSelector class.
122cab237bSDimitry Andric //
13d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===//
14d88c1a5aSDimitry Andric 
15d88c1a5aSDimitry Andric #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
16d88c1a5aSDimitry Andric #include "llvm/CodeGen/GlobalISel/Utils.h"
17a580b014SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
18a580b014SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
19d88c1a5aSDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
20a580b014SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
21c4394386SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
222cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
23a580b014SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
24a580b014SDimitry Andric #include "llvm/Support/Debug.h"
25a580b014SDimitry Andric #include "llvm/Support/raw_ostream.h"
26a580b014SDimitry Andric #include <cassert>
27d88c1a5aSDimitry Andric 
28d88c1a5aSDimitry Andric #define DEBUG_TYPE "instructionselector"
29d88c1a5aSDimitry Andric 
30d88c1a5aSDimitry Andric using namespace llvm;
31d88c1a5aSDimitry Andric 
MatcherState(unsigned MaxRenderers)32c4394386SDimitry Andric InstructionSelector::MatcherState::MatcherState(unsigned MaxRenderers)
332cab237bSDimitry Andric     : Renderers(MaxRenderers), MIs() {}
34c4394386SDimitry Andric 
35a580b014SDimitry Andric InstructionSelector::InstructionSelector() = default;
36d88c1a5aSDimitry Andric 
constrainOperandRegToRegClass(MachineInstr & I,unsigned OpIdx,const TargetRegisterClass & RC,const TargetInstrInfo & TII,const TargetRegisterInfo & TRI,const RegisterBankInfo & RBI) const37edd7eaddSDimitry Andric bool InstructionSelector::constrainOperandRegToRegClass(
38edd7eaddSDimitry Andric     MachineInstr &I, unsigned OpIdx, const TargetRegisterClass &RC,
39edd7eaddSDimitry Andric     const TargetInstrInfo &TII, const TargetRegisterInfo &TRI,
40edd7eaddSDimitry Andric     const RegisterBankInfo &RBI) const {
41edd7eaddSDimitry Andric   MachineBasicBlock &MBB = *I.getParent();
42edd7eaddSDimitry Andric   MachineFunction &MF = *MBB.getParent();
43edd7eaddSDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
44edd7eaddSDimitry Andric 
45a580b014SDimitry Andric   return
46a580b014SDimitry Andric       constrainRegToClass(MRI, TII, RBI, I, I.getOperand(OpIdx).getReg(), RC);
47edd7eaddSDimitry Andric }
48edd7eaddSDimitry Andric 
isOperandImmEqual(const MachineOperand & MO,int64_t Value,const MachineRegisterInfo & MRI) const497a7e6055SDimitry Andric bool InstructionSelector::isOperandImmEqual(
507a7e6055SDimitry Andric     const MachineOperand &MO, int64_t Value,
517a7e6055SDimitry Andric     const MachineRegisterInfo &MRI) const {
52d8866befSDimitry Andric   if (MO.isReg() && MO.getReg())
537a7e6055SDimitry Andric     if (auto VRegVal = getConstantVRegVal(MO.getReg(), MRI))
547a7e6055SDimitry Andric       return *VRegVal == Value;
557a7e6055SDimitry Andric   return false;
567a7e6055SDimitry Andric }
577a7e6055SDimitry Andric 
isBaseWithConstantOffset(const MachineOperand & Root,const MachineRegisterInfo & MRI) const582cab237bSDimitry Andric bool InstructionSelector::isBaseWithConstantOffset(
592cab237bSDimitry Andric     const MachineOperand &Root, const MachineRegisterInfo &MRI) const {
602cab237bSDimitry Andric   if (!Root.isReg())
612cab237bSDimitry Andric     return false;
622cab237bSDimitry Andric 
632cab237bSDimitry Andric   MachineInstr *RootI = MRI.getVRegDef(Root.getReg());
642cab237bSDimitry Andric   if (RootI->getOpcode() != TargetOpcode::G_GEP)
652cab237bSDimitry Andric     return false;
662cab237bSDimitry Andric 
672cab237bSDimitry Andric   MachineOperand &RHS = RootI->getOperand(2);
682cab237bSDimitry Andric   MachineInstr *RHSI = MRI.getVRegDef(RHS.getReg());
692cab237bSDimitry Andric   if (RHSI->getOpcode() != TargetOpcode::G_CONSTANT)
702cab237bSDimitry Andric     return false;
712cab237bSDimitry Andric 
722cab237bSDimitry Andric   return true;
732cab237bSDimitry Andric }
742cab237bSDimitry Andric 
isObviouslySafeToFold(MachineInstr & MI,MachineInstr & IntoMI) const752cab237bSDimitry Andric bool InstructionSelector::isObviouslySafeToFold(MachineInstr &MI,
762cab237bSDimitry Andric                                                 MachineInstr &IntoMI) const {
772cab237bSDimitry Andric   // Immediate neighbours are already folded.
782cab237bSDimitry Andric   if (MI.getParent() == IntoMI.getParent() &&
792cab237bSDimitry Andric       std::next(MI.getIterator()) == IntoMI.getIterator())
802cab237bSDimitry Andric     return true;
812cab237bSDimitry Andric 
827a7e6055SDimitry Andric   return !MI.mayLoadOrStore() && !MI.hasUnmodeledSideEffects() &&
83*b5893f02SDimitry Andric          empty(MI.implicit_operands());
847a7e6055SDimitry Andric }
85