10eae32dcSDimitry Andric //===- MachineSSAContext.cpp ------------------------------------*- C++ -*-===// 20eae32dcSDimitry Andric // 30eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60eae32dcSDimitry Andric // 70eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 80eae32dcSDimitry Andric /// \file 90eae32dcSDimitry Andric /// 100eae32dcSDimitry Andric /// This file defines a specialization of the GenericSSAContext<X> 110eae32dcSDimitry Andric /// template class for Machine IR. 120eae32dcSDimitry Andric /// 130eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 140eae32dcSDimitry Andric 150eae32dcSDimitry Andric #include "llvm/CodeGen/MachineSSAContext.h" 160eae32dcSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 1781ad6265SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 180eae32dcSDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 1981ad6265SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 200eae32dcSDimitry Andric #include "llvm/Support/raw_ostream.h" 210eae32dcSDimitry Andric 220eae32dcSDimitry Andric using namespace llvm; 230eae32dcSDimitry Andric 24bdd1243dSDimitry Andric const Register MachineSSAContext::ValueRefNull{}; 250eae32dcSDimitry Andric 260eae32dcSDimitry Andric void MachineSSAContext::setFunction(MachineFunction &Fn) { 270eae32dcSDimitry Andric MF = &Fn; 280eae32dcSDimitry Andric RegInfo = &MF->getRegInfo(); 290eae32dcSDimitry Andric } 300eae32dcSDimitry Andric 31bdd1243dSDimitry Andric MachineBasicBlock *MachineSSAContext::getEntryBlock(MachineFunction &F) { 32bdd1243dSDimitry Andric return &F.front(); 33bdd1243dSDimitry Andric } 34bdd1243dSDimitry Andric 35bdd1243dSDimitry Andric void MachineSSAContext::appendBlockTerms( 36bdd1243dSDimitry Andric SmallVectorImpl<const MachineInstr *> &terms, 37bdd1243dSDimitry Andric const MachineBasicBlock &block) { 38bdd1243dSDimitry Andric for (auto &T : block.terminators()) 39bdd1243dSDimitry Andric terms.push_back(&T); 40bdd1243dSDimitry Andric } 41bdd1243dSDimitry Andric 42bdd1243dSDimitry Andric void MachineSSAContext::appendBlockDefs(SmallVectorImpl<Register> &defs, 43bdd1243dSDimitry Andric const MachineBasicBlock &block) { 44bdd1243dSDimitry Andric for (const MachineInstr &instr : block.instrs()) { 45bdd1243dSDimitry Andric for (const MachineOperand &op : instr.operands()) { 46bdd1243dSDimitry Andric if (op.isReg() && op.isDef()) 47bdd1243dSDimitry Andric defs.push_back(op.getReg()); 48bdd1243dSDimitry Andric } 49bdd1243dSDimitry Andric } 50bdd1243dSDimitry Andric } 51bdd1243dSDimitry Andric 52bdd1243dSDimitry Andric /// Get the defining block of a value. 53bdd1243dSDimitry Andric MachineBasicBlock *MachineSSAContext::getDefBlock(Register value) const { 54bdd1243dSDimitry Andric if (!value) 55bdd1243dSDimitry Andric return nullptr; 56bdd1243dSDimitry Andric return RegInfo->getVRegDef(value)->getParent(); 57bdd1243dSDimitry Andric } 58bdd1243dSDimitry Andric 59bdd1243dSDimitry Andric bool MachineSSAContext::isConstantValuePhi(const MachineInstr &Phi) { 60bdd1243dSDimitry Andric return Phi.isConstantValuePHI(); 61bdd1243dSDimitry Andric } 62bdd1243dSDimitry Andric 63bdd1243dSDimitry Andric Printable MachineSSAContext::print(const MachineBasicBlock *Block) const { 64bdd1243dSDimitry Andric if (!Block) 65bdd1243dSDimitry Andric return Printable([](raw_ostream &Out) { Out << "<nullptr>"; }); 660eae32dcSDimitry Andric return Printable([Block](raw_ostream &Out) { Block->printName(Out); }); 670eae32dcSDimitry Andric } 680eae32dcSDimitry Andric 69bdd1243dSDimitry Andric Printable MachineSSAContext::print(const MachineInstr *I) const { 700eae32dcSDimitry Andric return Printable([I](raw_ostream &Out) { I->print(Out); }); 710eae32dcSDimitry Andric } 720eae32dcSDimitry Andric 730eae32dcSDimitry Andric Printable MachineSSAContext::print(Register Value) const { 740eae32dcSDimitry Andric auto *MRI = RegInfo; 750eae32dcSDimitry Andric return Printable([MRI, Value](raw_ostream &Out) { 760eae32dcSDimitry Andric Out << printReg(Value, MRI->getTargetRegisterInfo(), 0, MRI); 770eae32dcSDimitry Andric 780eae32dcSDimitry Andric if (Value) { 790eae32dcSDimitry Andric // Try to print the definition. 800eae32dcSDimitry Andric if (auto *Instr = MRI->getUniqueVRegDef(Value)) { 810eae32dcSDimitry Andric Out << ": "; 820eae32dcSDimitry Andric Instr->print(Out); 830eae32dcSDimitry Andric } 840eae32dcSDimitry Andric } 850eae32dcSDimitry Andric }); 860eae32dcSDimitry Andric } 87