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