xref: /freebsd-src/contrib/llvm-project/llvm/lib/Analysis/ValueLatticeUtils.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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 Andric bool llvm::canTrackArgumentsInterprocedurally(Function *F) {
200b57cec5SDimitry Andric   return F->hasLocalLinkage() && !F->hasAddressTaken();
210b57cec5SDimitry Andric }
220b57cec5SDimitry Andric 
canTrackReturnsInterprocedurally(Function * F)230b57cec5SDimitry Andric bool llvm::canTrackReturnsInterprocedurally(Function *F) {
240b57cec5SDimitry Andric   return F->hasExactDefinition() && !F->hasFnAttribute(Attribute::Naked);
250b57cec5SDimitry Andric }
260b57cec5SDimitry Andric 
canTrackGlobalVariableInterprocedurally(GlobalVariable * GV)270b57cec5SDimitry Andric bool 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