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