10eae32dcSDimitry Andric //===- SSAContext.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 LLVM IR. 120eae32dcSDimitry Andric /// 130eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 140eae32dcSDimitry Andric 150eae32dcSDimitry Andric #include "llvm/IR/SSAContext.h" 16bdd1243dSDimitry Andric #include "llvm/IR/Argument.h" 170eae32dcSDimitry Andric #include "llvm/IR/BasicBlock.h" 180eae32dcSDimitry Andric #include "llvm/IR/Function.h" 190eae32dcSDimitry Andric #include "llvm/IR/Instruction.h" 20bdd1243dSDimitry Andric #include "llvm/IR/Instructions.h" 210eae32dcSDimitry Andric #include "llvm/Support/raw_ostream.h" 220eae32dcSDimitry Andric 230eae32dcSDimitry Andric using namespace llvm; 240eae32dcSDimitry Andric 25bdd1243dSDimitry Andric void SSAContext::setFunction(Function &Fn) { F = &Fn; } 26bdd1243dSDimitry Andric 270eae32dcSDimitry Andric BasicBlock *SSAContext::getEntryBlock(Function &F) { 280eae32dcSDimitry Andric return &F.getEntryBlock(); 290eae32dcSDimitry Andric } 300eae32dcSDimitry Andric 31bdd1243dSDimitry Andric const BasicBlock *SSAContext::getEntryBlock(const Function &F) { 32bdd1243dSDimitry Andric return &F.getEntryBlock(); 33bdd1243dSDimitry Andric } 340eae32dcSDimitry Andric 35bdd1243dSDimitry Andric void SSAContext::appendBlockDefs(SmallVectorImpl<Value *> &defs, 36bdd1243dSDimitry Andric BasicBlock &block) { 37bdd1243dSDimitry Andric for (auto &instr : block.instructionsWithoutDebug(/*SkipPseudoOp=*/true)) { 38bdd1243dSDimitry Andric if (instr.isTerminator()) 39bdd1243dSDimitry Andric break; 40bdd1243dSDimitry Andric if (instr.getType()->isVoidTy()) 41bdd1243dSDimitry Andric continue; 42bdd1243dSDimitry Andric auto *def = &instr; 43bdd1243dSDimitry Andric defs.push_back(def); 44bdd1243dSDimitry Andric } 45bdd1243dSDimitry Andric } 46bdd1243dSDimitry Andric 47bdd1243dSDimitry Andric void SSAContext::appendBlockDefs(SmallVectorImpl<const Value *> &defs, 48bdd1243dSDimitry Andric const BasicBlock &block) { 49bdd1243dSDimitry Andric for (auto &instr : block) { 50bdd1243dSDimitry Andric if (instr.isTerminator()) 51bdd1243dSDimitry Andric break; 52bdd1243dSDimitry Andric defs.push_back(&instr); 53bdd1243dSDimitry Andric } 54bdd1243dSDimitry Andric } 55bdd1243dSDimitry Andric 56bdd1243dSDimitry Andric void SSAContext::appendBlockTerms(SmallVectorImpl<Instruction *> &terms, 57bdd1243dSDimitry Andric BasicBlock &block) { 58bdd1243dSDimitry Andric terms.push_back(block.getTerminator()); 59bdd1243dSDimitry Andric } 60bdd1243dSDimitry Andric 61bdd1243dSDimitry Andric void SSAContext::appendBlockTerms(SmallVectorImpl<const Instruction *> &terms, 62bdd1243dSDimitry Andric const BasicBlock &block) { 63bdd1243dSDimitry Andric terms.push_back(block.getTerminator()); 64bdd1243dSDimitry Andric } 65bdd1243dSDimitry Andric 66bdd1243dSDimitry Andric const BasicBlock *SSAContext::getDefBlock(const Value *value) const { 67bdd1243dSDimitry Andric if (const auto *instruction = dyn_cast<Instruction>(value)) 68bdd1243dSDimitry Andric return instruction->getParent(); 69bdd1243dSDimitry Andric return nullptr; 70bdd1243dSDimitry Andric } 71bdd1243dSDimitry Andric 72bdd1243dSDimitry Andric bool SSAContext::comesBefore(const Instruction *lhs, const Instruction *rhs) { 73bdd1243dSDimitry Andric return lhs->comesBefore(rhs); 74bdd1243dSDimitry Andric } 75bdd1243dSDimitry Andric 76*06c3fb27SDimitry Andric bool SSAContext::isConstantOrUndefValuePhi(const Instruction &Instr) { 77bdd1243dSDimitry Andric if (auto *Phi = dyn_cast<PHINode>(&Instr)) 78*06c3fb27SDimitry Andric return Phi->hasConstantOrUndefValue(); 79bdd1243dSDimitry Andric return false; 80bdd1243dSDimitry Andric } 81bdd1243dSDimitry Andric 82bdd1243dSDimitry Andric Printable SSAContext::print(const Value *V) const { 830eae32dcSDimitry Andric return Printable([V](raw_ostream &Out) { V->print(Out); }); 840eae32dcSDimitry Andric } 850eae32dcSDimitry Andric 86bdd1243dSDimitry Andric Printable SSAContext::print(const Instruction *Inst) const { 870eae32dcSDimitry Andric return print(cast<Value>(Inst)); 880eae32dcSDimitry Andric } 890eae32dcSDimitry Andric 90bdd1243dSDimitry Andric Printable SSAContext::print(const BasicBlock *BB) const { 91bdd1243dSDimitry Andric if (!BB) 92bdd1243dSDimitry Andric return Printable([](raw_ostream &Out) { Out << "<nullptr>"; }); 930eae32dcSDimitry Andric if (BB->hasName()) 940eae32dcSDimitry Andric return Printable([BB](raw_ostream &Out) { Out << BB->getName(); }); 950eae32dcSDimitry Andric 960eae32dcSDimitry Andric return Printable([BB](raw_ostream &Out) { 970eae32dcSDimitry Andric ModuleSlotTracker MST{BB->getParent()->getParent(), false}; 980eae32dcSDimitry Andric MST.incorporateFunction(*BB->getParent()); 990eae32dcSDimitry Andric Out << MST.getLocalSlot(BB); 1000eae32dcSDimitry Andric }); 1010eae32dcSDimitry Andric } 102