1 //===- SSAContext.cpp -------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// 10 /// This file defines a specialization of the GenericSSAContext<X> 11 /// template class for LLVM IR. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/IR/SSAContext.h" 16 #include "llvm/IR/BasicBlock.h" 17 #include "llvm/IR/Function.h" 18 #include "llvm/IR/Instructions.h" 19 #include "llvm/IR/Intrinsics.h" 20 #include "llvm/IR/ModuleSlotTracker.h" 21 #include "llvm/Support/raw_ostream.h" 22 23 using namespace llvm; 24 25 template <> 26 void SSAContext::appendBlockDefs(SmallVectorImpl<Value *> &defs, 27 BasicBlock &block) { 28 for (auto &instr : block) { 29 if (instr.isTerminator()) 30 break; 31 defs.push_back(&instr); 32 } 33 } 34 35 template <> 36 void SSAContext::appendBlockDefs(SmallVectorImpl<const Value *> &defs, 37 const BasicBlock &block) { 38 for (auto &instr : block) { 39 if (instr.isTerminator()) 40 break; 41 defs.push_back(&instr); 42 } 43 } 44 45 template <> 46 void SSAContext::appendBlockTerms(SmallVectorImpl<Instruction *> &terms, 47 BasicBlock &block) { 48 terms.push_back(block.getTerminator()); 49 } 50 51 template <> 52 void SSAContext::appendBlockTerms(SmallVectorImpl<const Instruction *> &terms, 53 const BasicBlock &block) { 54 terms.push_back(block.getTerminator()); 55 } 56 57 template <> 58 const BasicBlock *SSAContext::getDefBlock(const Value *value) const { 59 if (const auto *instruction = dyn_cast<Instruction>(value)) 60 return instruction->getParent(); 61 return nullptr; 62 } 63 64 template <> 65 bool SSAContext::isConstantOrUndefValuePhi(const Instruction &Instr) { 66 if (auto *Phi = dyn_cast<PHINode>(&Instr)) 67 return Phi->hasConstantOrUndefValue(); 68 return false; 69 } 70 71 template <> Intrinsic::ID SSAContext::getIntrinsicID(const Instruction &I) { 72 if (auto *CB = dyn_cast<CallBase>(&I)) 73 return CB->getIntrinsicID(); 74 return Intrinsic::not_intrinsic; 75 } 76 77 template <> Printable SSAContext::print(const Value *V) const { 78 return Printable([V](raw_ostream &Out) { V->print(Out); }); 79 } 80 81 template <> Printable SSAContext::print(const Instruction *Inst) const { 82 return print(cast<Value>(Inst)); 83 } 84 85 template <> Printable SSAContext::print(const BasicBlock *BB) const { 86 if (!BB) 87 return Printable([](raw_ostream &Out) { Out << "<nullptr>"; }); 88 if (BB->hasName()) 89 return Printable([BB](raw_ostream &Out) { Out << BB->getName(); }); 90 91 return Printable([BB](raw_ostream &Out) { 92 ModuleSlotTracker MST{BB->getParent()->getParent(), false}; 93 MST.incorporateFunction(*BB->getParent()); 94 Out << MST.getLocalSlot(BB); 95 }); 96 } 97 98 template <> Printable SSAContext::printAsOperand(const BasicBlock *BB) const { 99 return Printable([BB](raw_ostream &Out) { BB->printAsOperand(Out); }); 100 } 101