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