1317017Sdim//===- VNCoercion.h - Value Numbering Coercion Utilities --------*- C++ -*-===//
2317017Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6317017Sdim//
7317017Sdim//===----------------------------------------------------------------------===//
8317017Sdim/// \file / This file provides routines used by LLVM's value numbering passes to
9317017Sdim/// perform various forms of value extraction from memory when the types are not
10317017Sdim/// identical.  For example, given
11317017Sdim///
12317017Sdim/// store i32 8, i32 *%foo
13317017Sdim/// %a = bitcast i32 *%foo to i16
14317017Sdim/// %val = load i16, i16 *%a
15317017Sdim///
16317017Sdim/// It possible to extract the value of the load of %a from the store to %foo.
17317017Sdim/// These routines know how to tell whether they can do that (the analyze*
18317017Sdim/// routines), and can also insert the necessary IR to do it (the get*
19317017Sdim/// routines).
20317017Sdim
21317017Sdim#ifndef LLVM_TRANSFORMS_UTILS_VNCOERCION_H
22317017Sdim#define LLVM_TRANSFORMS_UTILS_VNCOERCION_H
23317017Sdim#include "llvm/IR/IRBuilder.h"
24317017Sdim
25317017Sdimnamespace llvm {
26317017Sdimclass Function;
27317017Sdimclass StoreInst;
28317017Sdimclass LoadInst;
29317017Sdimclass MemIntrinsic;
30317017Sdimclass Instruction;
31317017Sdimclass Value;
32317017Sdimclass Type;
33317017Sdimclass DataLayout;
34317017Sdimnamespace VNCoercion {
35317017Sdim/// Return true if CoerceAvailableValueToLoadType would succeed if it was
36317017Sdim/// called.
37317017Sdimbool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy,
38317017Sdim                                     const DataLayout &DL);
39317017Sdim
40317017Sdim/// If we saw a store of a value to memory, and then a load from a must-aliased
41317017Sdim/// pointer of a different type, try to coerce the stored value to the loaded
42317017Sdim/// type.  LoadedTy is the type of the load we want to replace.  IRB is
43317017Sdim/// IRBuilder used to insert new instructions.
44317017Sdim///
45317017Sdim/// If we can't do it, return null.
46317017SdimValue *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy,
47317017Sdim                                      IRBuilder<> &IRB, const DataLayout &DL);
48317017Sdim
49317017Sdim/// This function determines whether a value for the pointer LoadPtr can be
50317017Sdim/// extracted from the store at DepSI.
51317017Sdim///
52317017Sdim/// On success, it returns the offset into DepSI that extraction would start.
53317017Sdim/// On failure, it returns -1.
54317017Sdimint analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr,
55317017Sdim                                   StoreInst *DepSI, const DataLayout &DL);
56317017Sdim
57317017Sdim/// This function determines whether a value for the pointer LoadPtr can be
58317017Sdim/// extracted from the load at DepLI.
59317017Sdim///
60317017Sdim/// On success, it returns the offset into DepLI that extraction would start.
61317017Sdim/// On failure, it returns -1.
62317017Sdimint analyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, LoadInst *DepLI,
63317017Sdim                                  const DataLayout &DL);
64317017Sdim
65317017Sdim/// This function determines whether a value for the pointer LoadPtr can be
66317017Sdim/// extracted from the memory intrinsic at DepMI.
67317017Sdim///
68317017Sdim/// On success, it returns the offset into DepMI that extraction would start.
69317017Sdim/// On failure, it returns -1.
70317017Sdimint analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr,
71317017Sdim                                     MemIntrinsic *DepMI, const DataLayout &DL);
72317017Sdim
73317017Sdim/// If analyzeLoadFromClobberingStore returned an offset, this function can be
74317017Sdim/// used to actually perform the extraction of the bits from the store. It
75317017Sdim/// inserts instructions to do so at InsertPt, and returns the extracted value.
76317017SdimValue *getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy,
77317017Sdim                            Instruction *InsertPt, const DataLayout &DL);
78317017Sdim// This is the same as getStoreValueForLoad, except it performs no insertion
79317017Sdim// It only allows constant inputs.
80317017SdimConstant *getConstantStoreValueForLoad(Constant *SrcVal, unsigned Offset,
81317017Sdim                                       Type *LoadTy, const DataLayout &DL);
82317017Sdim
83317017Sdim/// If analyzeLoadFromClobberingLoad returned an offset, this function can be
84317017Sdim/// used to actually perform the extraction of the bits from the load, including
85317017Sdim/// any necessary load widening.  It inserts instructions to do so at InsertPt,
86317017Sdim/// and returns the extracted value.
87317017SdimValue *getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy,
88317017Sdim                           Instruction *InsertPt, const DataLayout &DL);
89317017Sdim// This is the same as getLoadValueForLoad, except it is given the load value as
90317017Sdim// a constant. It returns nullptr if it would require widening the load.
91317017SdimConstant *getConstantLoadValueForLoad(Constant *SrcVal, unsigned Offset,
92317017Sdim                                      Type *LoadTy, const DataLayout &DL);
93317017Sdim
94317017Sdim/// If analyzeLoadFromClobberingMemInst returned an offset, this function can be
95317017Sdim/// used to actually perform the extraction of the bits from the memory
96317017Sdim/// intrinsic.  It inserts instructions to do so at InsertPt, and returns the
97317017Sdim/// extracted value.
98317017SdimValue *getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset,
99317017Sdim                              Type *LoadTy, Instruction *InsertPt,
100317017Sdim                              const DataLayout &DL);
101317017Sdim// This is the same as getStoreValueForLoad, except it performs no insertion.
102317017Sdim// It returns nullptr if it cannot produce a constant.
103317017SdimConstant *getConstantMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset,
104317017Sdim                                         Type *LoadTy, const DataLayout &DL);
105317017Sdim}
106317017Sdim}
107317017Sdim#endif
108