11d0244aeSSameer Sahasrabuddhe //===- SSAContext.cpp -------------------------------------------*- C++ -*-===// 21d0244aeSSameer Sahasrabuddhe // 31d0244aeSSameer Sahasrabuddhe // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41d0244aeSSameer Sahasrabuddhe // See https://llvm.org/LICENSE.txt for license information. 51d0244aeSSameer Sahasrabuddhe // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61d0244aeSSameer Sahasrabuddhe // 71d0244aeSSameer Sahasrabuddhe //===----------------------------------------------------------------------===// 81d0244aeSSameer Sahasrabuddhe /// \file 91d0244aeSSameer Sahasrabuddhe /// 101d0244aeSSameer Sahasrabuddhe /// This file defines a specialization of the GenericSSAContext<X> 111d0244aeSSameer Sahasrabuddhe /// template class for LLVM IR. 121d0244aeSSameer Sahasrabuddhe /// 131d0244aeSSameer Sahasrabuddhe //===----------------------------------------------------------------------===// 141d0244aeSSameer Sahasrabuddhe 151d0244aeSSameer Sahasrabuddhe #include "llvm/IR/SSAContext.h" 161d0244aeSSameer Sahasrabuddhe #include "llvm/IR/BasicBlock.h" 171d0244aeSSameer Sahasrabuddhe #include "llvm/IR/Function.h" 18475ce4c2SSameer Sahasrabuddhe #include "llvm/IR/Instructions.h" 19*bd7a4d7bSSameer Sahasrabuddhe #include "llvm/IR/Intrinsics.h" 20466bd998SSameer Sahasrabuddhe #include "llvm/IR/ModuleSlotTracker.h" 21*bd7a4d7bSSameer Sahasrabuddhe #include "llvm/Support/raw_ostream.h" 221d0244aeSSameer Sahasrabuddhe 231d0244aeSSameer Sahasrabuddhe using namespace llvm; 241d0244aeSSameer Sahasrabuddhe 25b14e30f1SSameer Sahasrabuddhe template <> 26475ce4c2SSameer Sahasrabuddhe void SSAContext::appendBlockDefs(SmallVectorImpl<Value *> &defs, 27475ce4c2SSameer Sahasrabuddhe BasicBlock &block) { 28b14e30f1SSameer Sahasrabuddhe for (auto &instr : block) { 29475ce4c2SSameer Sahasrabuddhe if (instr.isTerminator()) 30475ce4c2SSameer Sahasrabuddhe break; 31b14e30f1SSameer Sahasrabuddhe defs.push_back(&instr); 32475ce4c2SSameer Sahasrabuddhe } 33475ce4c2SSameer Sahasrabuddhe } 34475ce4c2SSameer Sahasrabuddhe 35b14e30f1SSameer Sahasrabuddhe template <> 36475ce4c2SSameer Sahasrabuddhe void SSAContext::appendBlockDefs(SmallVectorImpl<const Value *> &defs, 37475ce4c2SSameer Sahasrabuddhe const BasicBlock &block) { 38475ce4c2SSameer Sahasrabuddhe for (auto &instr : block) { 39475ce4c2SSameer Sahasrabuddhe if (instr.isTerminator()) 40475ce4c2SSameer Sahasrabuddhe break; 41475ce4c2SSameer Sahasrabuddhe defs.push_back(&instr); 42475ce4c2SSameer Sahasrabuddhe } 43475ce4c2SSameer Sahasrabuddhe } 44475ce4c2SSameer Sahasrabuddhe 45b14e30f1SSameer Sahasrabuddhe template <> 46475ce4c2SSameer Sahasrabuddhe void SSAContext::appendBlockTerms(SmallVectorImpl<Instruction *> &terms, 47475ce4c2SSameer Sahasrabuddhe BasicBlock &block) { 48475ce4c2SSameer Sahasrabuddhe terms.push_back(block.getTerminator()); 49475ce4c2SSameer Sahasrabuddhe } 50475ce4c2SSameer Sahasrabuddhe 51b14e30f1SSameer Sahasrabuddhe template <> 52475ce4c2SSameer Sahasrabuddhe void SSAContext::appendBlockTerms(SmallVectorImpl<const Instruction *> &terms, 53475ce4c2SSameer Sahasrabuddhe const BasicBlock &block) { 54475ce4c2SSameer Sahasrabuddhe terms.push_back(block.getTerminator()); 55475ce4c2SSameer Sahasrabuddhe } 56475ce4c2SSameer Sahasrabuddhe 57b14e30f1SSameer Sahasrabuddhe template <> 58475ce4c2SSameer Sahasrabuddhe const BasicBlock *SSAContext::getDefBlock(const Value *value) const { 59475ce4c2SSameer Sahasrabuddhe if (const auto *instruction = dyn_cast<Instruction>(value)) 60475ce4c2SSameer Sahasrabuddhe return instruction->getParent(); 61475ce4c2SSameer Sahasrabuddhe return nullptr; 62475ce4c2SSameer Sahasrabuddhe } 63475ce4c2SSameer Sahasrabuddhe 64b14e30f1SSameer Sahasrabuddhe template <> 65f6e22f2fSSameer Sahasrabuddhe bool SSAContext::isConstantOrUndefValuePhi(const Instruction &Instr) { 66475ce4c2SSameer Sahasrabuddhe if (auto *Phi = dyn_cast<PHINode>(&Instr)) 67f6e22f2fSSameer Sahasrabuddhe return Phi->hasConstantOrUndefValue(); 68475ce4c2SSameer Sahasrabuddhe return false; 69475ce4c2SSameer Sahasrabuddhe } 70475ce4c2SSameer Sahasrabuddhe 71*bd7a4d7bSSameer Sahasrabuddhe template <> Intrinsic::ID SSAContext::getIntrinsicID(const Instruction &I) { 72*bd7a4d7bSSameer Sahasrabuddhe if (auto *CB = dyn_cast<CallBase>(&I)) 73*bd7a4d7bSSameer Sahasrabuddhe return CB->getIntrinsicID(); 74*bd7a4d7bSSameer Sahasrabuddhe return Intrinsic::not_intrinsic; 75*bd7a4d7bSSameer Sahasrabuddhe } 76*bd7a4d7bSSameer Sahasrabuddhe 77b14e30f1SSameer Sahasrabuddhe template <> Printable SSAContext::print(const Value *V) const { 781d0244aeSSameer Sahasrabuddhe return Printable([V](raw_ostream &Out) { V->print(Out); }); 791d0244aeSSameer Sahasrabuddhe } 801d0244aeSSameer Sahasrabuddhe 81b14e30f1SSameer Sahasrabuddhe template <> Printable SSAContext::print(const Instruction *Inst) const { 821d0244aeSSameer Sahasrabuddhe return print(cast<Value>(Inst)); 831d0244aeSSameer Sahasrabuddhe } 841d0244aeSSameer Sahasrabuddhe 85b14e30f1SSameer Sahasrabuddhe template <> Printable SSAContext::print(const BasicBlock *BB) const { 86475ce4c2SSameer Sahasrabuddhe if (!BB) 87475ce4c2SSameer Sahasrabuddhe return Printable([](raw_ostream &Out) { Out << "<nullptr>"; }); 881d0244aeSSameer Sahasrabuddhe if (BB->hasName()) 891d0244aeSSameer Sahasrabuddhe return Printable([BB](raw_ostream &Out) { Out << BB->getName(); }); 901d0244aeSSameer Sahasrabuddhe 911d0244aeSSameer Sahasrabuddhe return Printable([BB](raw_ostream &Out) { 921d0244aeSSameer Sahasrabuddhe ModuleSlotTracker MST{BB->getParent()->getParent(), false}; 931d0244aeSSameer Sahasrabuddhe MST.incorporateFunction(*BB->getParent()); 941d0244aeSSameer Sahasrabuddhe Out << MST.getLocalSlot(BB); 951d0244aeSSameer Sahasrabuddhe }); 961d0244aeSSameer Sahasrabuddhe } 97*bd7a4d7bSSameer Sahasrabuddhe 98*bd7a4d7bSSameer Sahasrabuddhe template <> Printable SSAContext::printAsOperand(const BasicBlock *BB) const { 99*bd7a4d7bSSameer Sahasrabuddhe return Printable([BB](raw_ostream &Out) { BB->printAsOperand(Out); }); 100*bd7a4d7bSSameer Sahasrabuddhe } 101