101 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8/// \file9///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 23using namespace llvm;24 25template <>26void 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 35template <>36void 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 45template <>46void SSAContext::appendBlockTerms(SmallVectorImpl<Instruction *> &terms,47 BasicBlock &block) {48 terms.push_back(block.getTerminator());49}50 51template <>52void SSAContext::appendBlockTerms(SmallVectorImpl<const Instruction *> &terms,53 const BasicBlock &block) {54 terms.push_back(block.getTerminator());55}56 57template <>58const 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 64template <>65bool SSAContext::isConstantOrUndefValuePhi(const Instruction &Instr) {66 if (auto *Phi = dyn_cast<PHINode>(&Instr))67 return Phi->hasConstantOrUndefValue();68 return false;69}70 71template <> 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 77template <> Printable SSAContext::print(const Value *V) const {78 return Printable([V](raw_ostream &Out) { V->print(Out); });79}80 81template <> Printable SSAContext::print(const Instruction *Inst) const {82 return print(cast<Value>(Inst));83}84 85template <> 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 98template <> Printable SSAContext::printAsOperand(const BasicBlock *BB) const {99 return Printable([BB](raw_ostream &Out) { BB->printAsOperand(Out); });100}101