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/Argument.h" 17 #include "llvm/IR/BasicBlock.h" 18 #include "llvm/IR/Function.h" 19 #include "llvm/IR/Instruction.h" 20 #include "llvm/IR/Instructions.h" 21 #include "llvm/Support/raw_ostream.h" 22 23 using namespace llvm; 24 25 void SSAContext::setFunction(Function &Fn) { F = &Fn; } 26 27 BasicBlock *SSAContext::getEntryBlock(Function &F) { 28 return &F.getEntryBlock(); 29 } 30 31 const BasicBlock *SSAContext::getEntryBlock(const Function &F) { 32 return &F.getEntryBlock(); 33 } 34 35 void SSAContext::appendBlockDefs(SmallVectorImpl<Value *> &defs, 36 BasicBlock &block) { 37 for (auto &instr : block.instructionsWithoutDebug(/*SkipPseudoOp=*/true)) { 38 if (instr.isTerminator()) 39 break; 40 if (instr.getType()->isVoidTy()) 41 continue; 42 auto *def = &instr; 43 defs.push_back(def); 44 } 45 } 46 47 void SSAContext::appendBlockDefs(SmallVectorImpl<const Value *> &defs, 48 const BasicBlock &block) { 49 for (auto &instr : block) { 50 if (instr.isTerminator()) 51 break; 52 defs.push_back(&instr); 53 } 54 } 55 56 void SSAContext::appendBlockTerms(SmallVectorImpl<Instruction *> &terms, 57 BasicBlock &block) { 58 terms.push_back(block.getTerminator()); 59 } 60 61 void SSAContext::appendBlockTerms(SmallVectorImpl<const Instruction *> &terms, 62 const BasicBlock &block) { 63 terms.push_back(block.getTerminator()); 64 } 65 66 const BasicBlock *SSAContext::getDefBlock(const Value *value) const { 67 if (const auto *instruction = dyn_cast<Instruction>(value)) 68 return instruction->getParent(); 69 return nullptr; 70 } 71 72 bool SSAContext::comesBefore(const Instruction *lhs, const Instruction *rhs) { 73 return lhs->comesBefore(rhs); 74 } 75 76 bool SSAContext::isConstantOrUndefValuePhi(const Instruction &Instr) { 77 if (auto *Phi = dyn_cast<PHINode>(&Instr)) 78 return Phi->hasConstantOrUndefValue(); 79 return false; 80 } 81 82 Printable SSAContext::print(const Value *V) const { 83 return Printable([V](raw_ostream &Out) { V->print(Out); }); 84 } 85 86 Printable SSAContext::print(const Instruction *Inst) const { 87 return print(cast<Value>(Inst)); 88 } 89 90 Printable SSAContext::print(const BasicBlock *BB) const { 91 if (!BB) 92 return Printable([](raw_ostream &Out) { Out << "<nullptr>"; }); 93 if (BB->hasName()) 94 return Printable([BB](raw_ostream &Out) { Out << BB->getName(); }); 95 96 return Printable([BB](raw_ostream &Out) { 97 ModuleSlotTracker MST{BB->getParent()->getParent(), false}; 98 MST.incorporateFunction(*BB->getParent()); 99 Out << MST.getLocalSlot(BB); 100 }); 101 } 102