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