10b57cec5SDimitry Andric //===-- ValueLatticeUtils.cpp - Utils for solving lattices ------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements common functions useful for performing data-flow 100b57cec5SDimitry Andric // analyses that propagate values across function boundaries. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/Analysis/ValueLatticeUtils.h" 150b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 160b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 170b57cec5SDimitry Andric using namespace llvm; 180b57cec5SDimitry Andric canTrackArgumentsInterprocedurally(Function * F)190b57cec5SDimitry Andricbool llvm::canTrackArgumentsInterprocedurally(Function *F) { 200b57cec5SDimitry Andric return F->hasLocalLinkage() && !F->hasAddressTaken(); 210b57cec5SDimitry Andric } 220b57cec5SDimitry Andric canTrackReturnsInterprocedurally(Function * F)230b57cec5SDimitry Andricbool llvm::canTrackReturnsInterprocedurally(Function *F) { 240b57cec5SDimitry Andric return F->hasExactDefinition() && !F->hasFnAttribute(Attribute::Naked); 250b57cec5SDimitry Andric } 260b57cec5SDimitry Andric canTrackGlobalVariableInterprocedurally(GlobalVariable * GV)270b57cec5SDimitry Andricbool llvm::canTrackGlobalVariableInterprocedurally(GlobalVariable *GV) { 280b57cec5SDimitry Andric if (GV->isConstant() || !GV->hasLocalLinkage() || 290b57cec5SDimitry Andric !GV->hasDefinitiveInitializer()) 300b57cec5SDimitry Andric return false; 315ffd83dbSDimitry Andric return all_of(GV->users(), [&](User *U) { 32*81ad6265SDimitry Andric // Currently all users of a global variable have to be non-volatile loads 33*81ad6265SDimitry Andric // or stores of the global type, and the global cannot be stored itself. 345ffd83dbSDimitry Andric if (auto *Store = dyn_cast<StoreInst>(U)) 35*81ad6265SDimitry Andric return Store->getValueOperand() != GV && !Store->isVolatile() && 36*81ad6265SDimitry Andric Store->getValueOperand()->getType() == GV->getValueType(); 375ffd83dbSDimitry Andric if (auto *Load = dyn_cast<LoadInst>(U)) 38*81ad6265SDimitry Andric return !Load->isVolatile() && Load->getType() == GV->getValueType(); 395ffd83dbSDimitry Andric 400b57cec5SDimitry Andric return false; 410b57cec5SDimitry Andric }); 420b57cec5SDimitry Andric } 43