xref: /llvm-project/llvm/lib/CodeGen/MachineSSAContext.cpp (revision b60c118f53e6f7e5328e54dc26b4d6787030c02b)
11d0244aeSSameer Sahasrabuddhe //===- MachineSSAContext.cpp ------------------------------------*- C++ -*-===//
21d0244aeSSameer Sahasrabuddhe //
31d0244aeSSameer Sahasrabuddhe // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41d0244aeSSameer Sahasrabuddhe // See https://llvm.org/LICENSE.txt for license information.
51d0244aeSSameer Sahasrabuddhe // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61d0244aeSSameer Sahasrabuddhe //
71d0244aeSSameer Sahasrabuddhe //===----------------------------------------------------------------------===//
81d0244aeSSameer Sahasrabuddhe /// \file
91d0244aeSSameer Sahasrabuddhe ///
101d0244aeSSameer Sahasrabuddhe /// This file defines a specialization of the GenericSSAContext<X>
111d0244aeSSameer Sahasrabuddhe /// template class for Machine IR.
121d0244aeSSameer Sahasrabuddhe ///
131d0244aeSSameer Sahasrabuddhe //===----------------------------------------------------------------------===//
141d0244aeSSameer Sahasrabuddhe 
151d0244aeSSameer Sahasrabuddhe #include "llvm/CodeGen/MachineSSAContext.h"
16bd7a4d7bSSameer Sahasrabuddhe #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
171d0244aeSSameer Sahasrabuddhe #include "llvm/CodeGen/MachineBasicBlock.h"
18989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachineFunction.h"
191d0244aeSSameer Sahasrabuddhe #include "llvm/CodeGen/MachineInstr.h"
20989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachineRegisterInfo.h"
211d0244aeSSameer Sahasrabuddhe #include "llvm/Support/raw_ostream.h"
221d0244aeSSameer Sahasrabuddhe 
231d0244aeSSameer Sahasrabuddhe using namespace llvm;
241d0244aeSSameer Sahasrabuddhe 
25b14e30f1SSameer Sahasrabuddhe template <>
26b14e30f1SSameer Sahasrabuddhe void MachineSSAContext::appendBlockDefs(SmallVectorImpl<Register> &defs,
27b14e30f1SSameer Sahasrabuddhe                                         const MachineBasicBlock &block) {
28b14e30f1SSameer Sahasrabuddhe   for (auto &instr : block.instrs()) {
29b14e30f1SSameer Sahasrabuddhe     for (auto &op : instr.all_defs())
30b14e30f1SSameer Sahasrabuddhe       defs.push_back(op.getReg());
31b14e30f1SSameer Sahasrabuddhe   }
321d0244aeSSameer Sahasrabuddhe }
331d0244aeSSameer Sahasrabuddhe 
34b14e30f1SSameer Sahasrabuddhe template <>
35b14e30f1SSameer Sahasrabuddhe void MachineSSAContext::appendBlockTerms(SmallVectorImpl<MachineInstr *> &terms,
36b14e30f1SSameer Sahasrabuddhe                                          MachineBasicBlock &block) {
37b14e30f1SSameer Sahasrabuddhe   for (auto &T : block.terminators())
38b14e30f1SSameer Sahasrabuddhe     terms.push_back(&T);
39475ce4c2SSameer Sahasrabuddhe }
40475ce4c2SSameer Sahasrabuddhe 
41b14e30f1SSameer Sahasrabuddhe template <>
42475ce4c2SSameer Sahasrabuddhe void MachineSSAContext::appendBlockTerms(
43475ce4c2SSameer Sahasrabuddhe     SmallVectorImpl<const MachineInstr *> &terms,
44475ce4c2SSameer Sahasrabuddhe     const MachineBasicBlock &block) {
45475ce4c2SSameer Sahasrabuddhe   for (auto &T : block.terminators())
46475ce4c2SSameer Sahasrabuddhe     terms.push_back(&T);
47475ce4c2SSameer Sahasrabuddhe }
48475ce4c2SSameer Sahasrabuddhe 
49475ce4c2SSameer Sahasrabuddhe /// Get the defining block of a value.
50b14e30f1SSameer Sahasrabuddhe template <>
51b14e30f1SSameer Sahasrabuddhe const MachineBasicBlock *MachineSSAContext::getDefBlock(Register value) const {
52475ce4c2SSameer Sahasrabuddhe   if (!value)
53475ce4c2SSameer Sahasrabuddhe     return nullptr;
54b14e30f1SSameer Sahasrabuddhe   return F->getRegInfo().getVRegDef(value)->getParent();
55475ce4c2SSameer Sahasrabuddhe }
56475ce4c2SSameer Sahasrabuddhe 
57*b60c118fSPetar Avramovic static bool isUndef(const MachineInstr &MI) {
58*b60c118fSPetar Avramovic   return MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
59*b60c118fSPetar Avramovic          MI.getOpcode() == TargetOpcode::IMPLICIT_DEF;
60*b60c118fSPetar Avramovic }
61*b60c118fSPetar Avramovic 
62*b60c118fSPetar Avramovic /// MachineInstr equivalent of PHINode::hasConstantOrUndefValue() for G_PHI.
63b14e30f1SSameer Sahasrabuddhe template <>
64f6e22f2fSSameer Sahasrabuddhe bool MachineSSAContext::isConstantOrUndefValuePhi(const MachineInstr &Phi) {
65*b60c118fSPetar Avramovic   if (!Phi.isPHI())
66*b60c118fSPetar Avramovic     return false;
67*b60c118fSPetar Avramovic 
68*b60c118fSPetar Avramovic   // In later passes PHI may appear with an undef operand, getVRegDef can fail.
69*b60c118fSPetar Avramovic   if (Phi.getOpcode() == TargetOpcode::PHI)
70475ce4c2SSameer Sahasrabuddhe     return Phi.isConstantValuePHI();
71*b60c118fSPetar Avramovic 
72*b60c118fSPetar Avramovic   // For G_PHI we do equivalent of PHINode::hasConstantOrUndefValue().
73*b60c118fSPetar Avramovic   const MachineRegisterInfo &MRI = Phi.getMF()->getRegInfo();
74*b60c118fSPetar Avramovic   Register This = Phi.getOperand(0).getReg();
75*b60c118fSPetar Avramovic   Register ConstantValue;
76*b60c118fSPetar Avramovic   for (unsigned i = 1, e = Phi.getNumOperands(); i < e; i += 2) {
77*b60c118fSPetar Avramovic     Register Incoming = Phi.getOperand(i).getReg();
78*b60c118fSPetar Avramovic     if (Incoming != This && !isUndef(*MRI.getVRegDef(Incoming))) {
79*b60c118fSPetar Avramovic       if (ConstantValue && ConstantValue != Incoming)
80*b60c118fSPetar Avramovic         return false;
81*b60c118fSPetar Avramovic       ConstantValue = Incoming;
82*b60c118fSPetar Avramovic     }
83*b60c118fSPetar Avramovic   }
84*b60c118fSPetar Avramovic   return true;
85475ce4c2SSameer Sahasrabuddhe }
86475ce4c2SSameer Sahasrabuddhe 
87b14e30f1SSameer Sahasrabuddhe template <>
88bd7a4d7bSSameer Sahasrabuddhe Intrinsic::ID MachineSSAContext::getIntrinsicID(const MachineInstr &MI) {
89bd7a4d7bSSameer Sahasrabuddhe   if (auto *GI = dyn_cast<GIntrinsic>(&MI))
90bd7a4d7bSSameer Sahasrabuddhe     return GI->getIntrinsicID();
91bd7a4d7bSSameer Sahasrabuddhe   return Intrinsic::not_intrinsic;
92bd7a4d7bSSameer Sahasrabuddhe }
93bd7a4d7bSSameer Sahasrabuddhe 
94bd7a4d7bSSameer Sahasrabuddhe template <>
95475ce4c2SSameer Sahasrabuddhe Printable MachineSSAContext::print(const MachineBasicBlock *Block) const {
96475ce4c2SSameer Sahasrabuddhe   if (!Block)
97475ce4c2SSameer Sahasrabuddhe     return Printable([](raw_ostream &Out) { Out << "<nullptr>"; });
981d0244aeSSameer Sahasrabuddhe   return Printable([Block](raw_ostream &Out) { Block->printName(Out); });
991d0244aeSSameer Sahasrabuddhe }
1001d0244aeSSameer Sahasrabuddhe 
101b14e30f1SSameer Sahasrabuddhe template <> Printable MachineSSAContext::print(const MachineInstr *I) const {
1021d0244aeSSameer Sahasrabuddhe   return Printable([I](raw_ostream &Out) { I->print(Out); });
1031d0244aeSSameer Sahasrabuddhe }
1041d0244aeSSameer Sahasrabuddhe 
105b14e30f1SSameer Sahasrabuddhe template <> Printable MachineSSAContext::print(Register Value) const {
106b14e30f1SSameer Sahasrabuddhe   auto *MRI = &F->getRegInfo();
1071d0244aeSSameer Sahasrabuddhe   return Printable([MRI, Value](raw_ostream &Out) {
1081d0244aeSSameer Sahasrabuddhe     Out << printReg(Value, MRI->getTargetRegisterInfo(), 0, MRI);
1091d0244aeSSameer Sahasrabuddhe 
1101d0244aeSSameer Sahasrabuddhe     if (Value) {
1111d0244aeSSameer Sahasrabuddhe       // Try to print the definition.
1121d0244aeSSameer Sahasrabuddhe       if (auto *Instr = MRI->getUniqueVRegDef(Value)) {
1131d0244aeSSameer Sahasrabuddhe         Out << ": ";
1141d0244aeSSameer Sahasrabuddhe         Instr->print(Out);
1151d0244aeSSameer Sahasrabuddhe       }
1161d0244aeSSameer Sahasrabuddhe     }
1171d0244aeSSameer Sahasrabuddhe   });
1181d0244aeSSameer Sahasrabuddhe }
119bd7a4d7bSSameer Sahasrabuddhe 
120bd7a4d7bSSameer Sahasrabuddhe template <>
121bd7a4d7bSSameer Sahasrabuddhe Printable MachineSSAContext::printAsOperand(const MachineBasicBlock *BB) const {
122bd7a4d7bSSameer Sahasrabuddhe   return Printable([BB](raw_ostream &Out) { BB->printAsOperand(Out); });
123bd7a4d7bSSameer Sahasrabuddhe }
124