|
LLVM
4.0.0
|
#include "llvm/Transforms/Scalar/GVN.h"#include "llvm/ADT/DenseMap.h"#include "llvm/ADT/DepthFirstIterator.h"#include "llvm/ADT/Hashing.h"#include "llvm/ADT/MapVector.h"#include "llvm/ADT/PostOrderIterator.h"#include "llvm/ADT/SetVector.h"#include "llvm/ADT/SmallPtrSet.h"#include "llvm/ADT/Statistic.h"#include "llvm/Analysis/AliasAnalysis.h"#include "llvm/Analysis/AssumptionCache.h"#include "llvm/Analysis/CFG.h"#include "llvm/Analysis/ConstantFolding.h"#include "llvm/Analysis/GlobalsModRef.h"#include "llvm/Analysis/InstructionSimplify.h"#include "llvm/Analysis/Loads.h"#include "llvm/Analysis/MemoryBuiltins.h"#include "llvm/Analysis/MemoryDependenceAnalysis.h"#include "llvm/Analysis/OptimizationDiagnosticInfo.h"#include "llvm/Analysis/PHITransAddr.h"#include "llvm/Analysis/TargetLibraryInfo.h"#include "llvm/Analysis/ValueTracking.h"#include "llvm/IR/DataLayout.h"#include "llvm/IR/Dominators.h"#include "llvm/IR/GlobalVariable.h"#include "llvm/IR/IRBuilder.h"#include "llvm/IR/IntrinsicInst.h"#include "llvm/IR/LLVMContext.h"#include "llvm/IR/Metadata.h"#include "llvm/IR/PatternMatch.h"#include "llvm/Support/CommandLine.h"#include "llvm/Support/Debug.h"#include "llvm/Support/raw_ostream.h"#include "llvm/Transforms/Utils/BasicBlockUtils.h"#include "llvm/Transforms/Utils/Local.h"#include "llvm/Transforms/Utils/SSAUpdater.h"#include <vector>Go to the source code of this file.
Classes | |
| struct | llvm::GVN::Expression |
| struct | llvm::DenseMapInfo< GVN::Expression > |
| struct | llvm::gvn::AvailableValue |
| Represents a particular available value that we know how to materialize. More... | |
| struct | llvm::gvn::AvailableValueInBlock |
| Represents an AvailableValue which can be rematerialized at the end of the associated BasicBlock. More... | |
| class | llvm::gvn::GVNLegacyPass |
Namespaces | |
| llvm | |
| Compute iterated dominance frontiers using a linear time algorithm. | |
Macros | |
| #define | DEBUG_TYPE "gvn" |
Functions | |
| STATISTIC (NumGVNInstr,"Number of instructions deleted") | |
| STATISTIC (NumGVNLoad,"Number of loads deleted") | |
| STATISTIC (NumGVNPRE,"Number of instructions PRE'd") | |
| STATISTIC (NumGVNBlocks,"Number of blocks merged") | |
| STATISTIC (NumGVNSimpl,"Number of instructions simplified") | |
| STATISTIC (NumGVNEqProp,"Number of equalities propagated") | |
| STATISTIC (NumPRELoad,"Number of loads PRE'd") | |
| static bool | IsValueFullyAvailableInBlock (BasicBlock *BB, DenseMap< BasicBlock *, char > &FullyAvailableBlocks, uint32_t RecurseDepth) |
| Return true if we can prove that the value we're analyzing is fully available in the specified block. More... | |
| static bool | CanCoerceMustAliasedValueToLoad (Value *StoredVal, Type *LoadTy, const DataLayout &DL) |
| Return true if CoerceAvailableValueToLoadType will succeed. More... | |
| static Value * | CoerceAvailableValueToLoadType (Value *StoredVal, Type *LoadedTy, IRBuilder<> &IRB, const DataLayout &DL) |
| If we saw a store of a value to memory, and then a load from a must-aliased pointer of a different type, try to coerce the stored value. More... | |
| static int | AnalyzeLoadFromClobberingWrite (Type *LoadTy, Value *LoadPtr, Value *WritePtr, uint64_t WriteSizeInBits, const DataLayout &DL) |
| This function is called when we have a memdep query of a load that ends up being a clobbering memory write (store, memset, memcpy, memmove). More... | |
| static int | AnalyzeLoadFromClobberingStore (Type *LoadTy, Value *LoadPtr, StoreInst *DepSI) |
| This function is called when we have a memdep query of a load that ends up being a clobbering store. More... | |
| static int | AnalyzeLoadFromClobberingLoad (Type *LoadTy, Value *LoadPtr, LoadInst *DepLI, const DataLayout &DL) |
| This function is called when we have a memdep query of a load that ends up being clobbered by another load. More... | |
| static int | AnalyzeLoadFromClobberingMemInst (Type *LoadTy, Value *LoadPtr, MemIntrinsic *MI, const DataLayout &DL) |
| static Value * | GetStoreValueForLoad (Value *SrcVal, unsigned Offset, Type *LoadTy, Instruction *InsertPt, const DataLayout &DL) |
| This function is called when we have a memdep query of a load that ends up being a clobbering store. More... | |
| static Value * | GetLoadValueForLoad (LoadInst *SrcVal, unsigned Offset, Type *LoadTy, Instruction *InsertPt, GVN &gvn) |
| This function is called when we have a memdep query of a load that ends up being a clobbering load. More... | |
| static Value * | GetMemInstValueForLoad (MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, Instruction *InsertPt, const DataLayout &DL) |
| This function is called when we have a memdep query of a load that ends up being a clobbering mem intrinsic. More... | |
| static Value * | ConstructSSAForLoadSet (LoadInst *LI, SmallVectorImpl< AvailableValueInBlock > &ValuesPerBlock, GVN &gvn) |
| Given a set of loads specified by ValuesPerBlock, construct SSA form, allowing us to eliminate LI. More... | |
| static bool | isLifetimeStart (const Instruction *Inst) |
| static void | reportMayClobberedLoad (LoadInst *LI, MemDepResult DepInfo, DominatorTree *DT, OptimizationRemarkEmitter *ORE) |
| Try to locate the three instruction involved in a missed load-elimination case that is due to an intervening store. More... | |
| static void | reportLoadElim (LoadInst *LI, Value *AvailableValue, OptimizationRemarkEmitter *ORE) |
| static void | patchReplacementInstruction (Instruction *I, Value *Repl) |
| static void | patchAndReplaceAllUsesWith (Instruction *I, Value *Repl) |
| static bool | isOnlyReachableViaThisEdge (const BasicBlockEdge &E, DominatorTree *DT) |
| There is an edge from 'Src' to 'Dst'. More... | |
Variables | |
| static cl::opt< bool > | EnablePRE ("enable-pre", cl::init(true), cl::Hidden) |
| static cl::opt< bool > | EnableLoadPRE ("enable-load-pre", cl::init(true)) |
| static cl::opt< uint32_t > | MaxRecurseDepth ("max-recurse-depth", cl::Hidden, cl::init(1000), cl::ZeroOrMore, cl::desc("Max recurse depth (default = 1000)")) |
| #define DEBUG_TYPE "gvn" |
Definition at line 59 of file GVN.cpp.
Referenced by reportLoadElim(), and reportMayClobberedLoad().
|
static |
This function is called when we have a memdep query of a load that ends up being clobbered by another load.
See if the other load can feed into the second load.
Definition at line 893 of file GVN.cpp.
References AnalyzeLoadFromClobberingWrite(), assert(), llvm::MemoryDependenceResults::getLoadLoadClobberFullWidthSize(), llvm::GetPointerBaseWithConstantOffset(), llvm::LoadInst::getPointerOperand(), llvm::Value::getType(), llvm::DataLayout::getTypeSizeInBits(), llvm::DataLayout::getTypeStoreSize(), llvm::Type::isArrayTy(), llvm::Type::isIntegerTy(), llvm::LoadInst::isSimple(), and llvm::Type::isStructTy().
|
static |
Definition at line 925 of file GVN.cpp.
References AnalyzeLoadFromClobberingWrite(), llvm::ConstantFoldLoadFromConstPtr(), llvm::dyn_cast(), llvm::ConstantInt::get(), llvm::PointerType::get(), llvm::ConstantExpr::getBitCast(), llvm::MemIntrinsic::getDest(), llvm::ConstantExpr::getGetElementPtr(), llvm::Type::getInt64Ty(), llvm::Type::getInt8PtrTy(), llvm::Type::getInt8Ty(), llvm::IntrinsicInst::getIntrinsicID(), llvm::MemIntrinsic::getLength(), llvm::MemTransferInst::getSource(), llvm::GetUnderlyingObject(), llvm::ConstantInt::getZExtValue(), llvm::GlobalVariable::isConstant(), MI, and Offset.
|
static |
This function is called when we have a memdep query of a load that ends up being a clobbering store.
Definition at line 876 of file GVN.cpp.
References AnalyzeLoadFromClobberingWrite(), llvm::Module::getDataLayout(), llvm::Instruction::getModule(), llvm::StoreInst::getPointerOperand(), llvm::Value::getType(), llvm::DataLayout::getTypeSizeInBits(), llvm::StoreInst::getValueOperand(), llvm::Type::isArrayTy(), and llvm::Type::isStructTy().
|
static |
This function is called when we have a memdep query of a load that ends up being a clobbering memory write (store, memset, memcpy, memmove).
This means that the write may provide bits used by the load but we can't be sure because the pointers don't mustalias.
Check this case to see if there is anything more we can do before we give up. This returns -1 if we have to give up, or a byte number in the stored value of the piece that feeds the load.
Definition at line 820 of file GVN.cpp.
References llvm::GetPointerBaseWithConstantOffset(), llvm::DataLayout::getTypeSizeInBits(), llvm::Type::isArrayTy(), and llvm::Type::isStructTy().
Referenced by AnalyzeLoadFromClobberingLoad(), AnalyzeLoadFromClobberingMemInst(), and AnalyzeLoadFromClobberingStore().
|
static |
Return true if CoerceAvailableValueToLoadType will succeed.
Definition at line 694 of file GVN.cpp.
References llvm::Value::getType(), llvm::DataLayout::getTypeSizeInBits(), llvm::Type::isArrayTy(), and llvm::Type::isStructTy().
Referenced by CoerceAvailableValueToLoadType().
|
static |
If we saw a store of a value to memory, and then a load from a must-aliased pointer of a different type, try to coerce the stored value.
LoadedTy is the type of the load we want to replace. IRB is IRBuilder used to insert new instructions.
If we can't do it, return null.
Definition at line 718 of file GVN.cpp.
References assert(), CanCoerceMustAliasedValueToLoad(), llvm::ConstantFoldConstant(), llvm::IRBuilder< T, Inserter >::CreateBitCast(), llvm::IRBuilder< T, Inserter >::CreateIntToPtr(), llvm::IRBuilder< T, Inserter >::CreateLShr(), llvm::IRBuilder< T, Inserter >::CreatePtrToInt(), llvm::IRBuilder< T, Inserter >::CreateTrunc(), llvm::IntegerType::get(), llvm::Type::getContext(), llvm::DataLayout::getIntPtrType(), llvm::Type::getScalarType(), llvm::Value::getType(), llvm::DataLayout::getTypeSizeInBits(), llvm::DataLayout::getTypeStoreSizeInBits(), llvm::DataLayout::isBigEndian(), llvm::Type::isIntegerTy(), and llvm::Type::isPointerTy().
Referenced by GetMemInstValueForLoad(), and GetStoreValueForLoad().
|
static |
Given a set of loads specified by ValuesPerBlock, construct SSA form, allowing us to eliminate LI.
This returns the value that should be used at LI's definition site.
Definition at line 1134 of file GVN.cpp.
References llvm::SSAUpdater::AddAvailableValue(), assert(), llvm::GVN::getDominatorTree(), llvm::Value::getName(), llvm::Instruction::getParent(), llvm::Value::getType(), llvm::SSAUpdater::GetValueInMiddleOfBlock(), llvm::SSAUpdater::HasValueForBlock(), llvm::SSAUpdater::Initialize(), llvm::DominatorTreeBase< N >::properlyDominates(), and llvm::SmallVectorTemplateCommon< T >::size().
|
static |
This function is called when we have a memdep query of a load that ends up being a clobbering load.
This means that the load may provide bits used by the load but we can't be sure because the pointers don't mustalias. Check this case to see if there is anything more we can do before we give up.
Definition at line 1016 of file GVN.cpp.
References assert(), llvm::dbgs(), DEBUG, llvm::IntegerType::get(), llvm::PointerType::get(), llvm::LoadInst::getAlignment(), llvm::Type::getContext(), llvm::Module::getDataLayout(), llvm::Instruction::getDebugLoc(), llvm::GVN::getMemDep(), llvm::Instruction::getModule(), llvm::Instruction::getParent(), llvm::Type::getPointerAddressSpace(), llvm::LoadInst::getPointerOperand(), GetStoreValueForLoad(), llvm::Value::getType(), llvm::DataLayout::getTypeStoreSize(), llvm::DataLayout::isBigEndian(), llvm::Type::isIntegerTy(), llvm::isPowerOf2_32(), llvm::LoadInst::isSimple(), llvm::NextPowerOf2(), llvm::MemoryDependenceResults::removeInstruction(), llvm::Value::replaceAllUsesWith(), llvm::LoadInst::setAlignment(), and llvm::Value::takeName().
Referenced by llvm::gvn::AvailableValue::MaterializeAdjustedValue().
|
static |
This function is called when we have a memdep query of a load that ends up being a clobbering mem intrinsic.
Definition at line 1075 of file GVN.cpp.
References CoerceAvailableValueToLoadType(), llvm::ConstantFoldLoadFromConstPtr(), llvm::IRBuilder< T, Inserter >::CreateOr(), llvm::IRBuilder< T, Inserter >::CreateShl(), llvm::IRBuilder< T, Inserter >::CreateZExt(), llvm::IntegerType::get(), llvm::ConstantInt::get(), llvm::PointerType::get(), llvm::ConstantExpr::getBitCast(), llvm::Type::getContext(), llvm::ConstantExpr::getGetElementPtr(), llvm::Type::getInt64Ty(), llvm::Type::getInt8PtrTy(), llvm::Type::getInt8Ty(), llvm::Type::getPointerAddressSpace(), llvm::MemTransferInst::getSource(), llvm::Value::getType(), llvm::DataLayout::getTypeSizeInBits(), and Offset.
Referenced by llvm::gvn::AvailableValue::MaterializeAdjustedValue().
|
static |
This function is called when we have a memdep query of a load that ends up being a clobbering store.
This means that the store provides bits used by the load but we the pointers don't mustalias. Check this case to see if there is anything more we can do before we give up.
Definition at line 977 of file GVN.cpp.
References CoerceAvailableValueToLoadType(), llvm::IRBuilder< T, Inserter >::CreateBitCast(), llvm::IRBuilder< T, Inserter >::CreateLShr(), llvm::IRBuilder< T, Inserter >::CreatePtrToInt(), llvm::IRBuilder< T, Inserter >::CreateTrunc(), llvm::IntegerType::get(), llvm::Type::getContext(), llvm::DataLayout::getIntPtrType(), llvm::Type::getScalarType(), llvm::Value::getType(), llvm::DataLayout::getTypeSizeInBits(), llvm::Type::isIntegerTy(), llvm::DataLayout::isLittleEndian(), llvm::Type::isPointerTy(), and Offset.
Referenced by GetLoadValueForLoad(), and llvm::gvn::AvailableValue::MaterializeAdjustedValue().
|
static |
|
static |
There is an edge from 'Src' to 'Dst'.
Return true if every path from the entry block to 'Dst' passes via this edge. In particular 'Dst' must not be reachable via another edge from 'Src'.
Definition at line 1911 of file GVN.cpp.
References assert(), llvm::BasicBlockEdge::getEnd(), llvm::BasicBlock::getSinglePredecessor(), and llvm::BasicBlockEdge::getStart().
|
static |
Return true if we can prove that the value we're analyzing is fully available in the specified block.
As we go, keep track of which blocks we know are fully alive in FullyAvailableBlocks. This map is actually a tri-state map with the following values: 0) we know the block is not fully available. 1) we know the block is fully available. 2) we do not know whether the block is fully available or not, but we are currently speculating that it will be. 3) we are speculating for this block and have used that to speculate for other blocks.
Definition at line 622 of file GVN.cpp.
References llvm::SmallVectorImpl< T >::append(), llvm::SmallVectorBase::empty(), llvm::DenseMapBase< DenseMap< KeyT, ValueT, KeyInfoT, BucketT >, KeyT, ValueT, KeyInfoT, BucketT >::insert(), MaxRecurseDepth, llvm::SmallVectorImpl< T >::pop_back_val(), llvm::pred_begin(), llvm::pred_end(), llvm::SmallVectorTemplateBase< T, isPodLike< T >::value >::push_back(), llvm::succ_begin(), and llvm::succ_end().
|
static |
Definition at line 1822 of file GVN.cpp.
References patchReplacementInstruction(), and llvm::Value::replaceAllUsesWith().
|
static |
Definition at line 1791 of file GVN.cpp.
References llvm::Instruction::andIRFlags(), llvm::combineMetadata(), llvm::dyn_cast(), llvm::LLVMContext::MD_alias_scope, llvm::LLVMContext::MD_fpmath, llvm::LLVMContext::MD_invariant_group, llvm::LLVMContext::MD_invariant_load, llvm::LLVMContext::MD_noalias, llvm::LLVMContext::MD_range, and llvm::LLVMContext::MD_tbaa.
Referenced by patchAndReplaceAllUsesWith().
|
static |
Definition at line 1640 of file GVN.cpp.
References DEBUG_TYPE, llvm::OptimizationRemarkEmitter::emit(), and llvm::Value::getType().
|
static |
Try to locate the three instruction involved in a missed load-elimination case that is due to an intervening store.
Definition at line 1214 of file GVN.cpp.
References DEBUG_TYPE, llvm::DominatorTree::dominates(), llvm::OptimizationRemarkEmitter::emit(), llvm::MemDepResult::getInst(), llvm::LoadInst::getPointerOperand(), llvm::Value::getType(), and llvm::Value::users().
| STATISTIC | ( | NumGVNInstr | , |
| "Number of instructions deleted" | |||
| ) |
| STATISTIC | ( | NumGVNLoad | , |
| "Number of loads deleted" | |||
| ) |
| STATISTIC | ( | NumGVNPRE | , |
| "Number of instructions PRE'd" | |||
| ) |
| STATISTIC | ( | NumGVNBlocks | , |
| "Number of blocks merged" | |||
| ) |
| STATISTIC | ( | NumGVNSimpl | , |
| "Number of instructions simplified" | |||
| ) |
| STATISTIC | ( | NumGVNEqProp | , |
| "Number of equalities propagated" | |||
| ) |
| STATISTIC | ( | NumPRELoad | , |
| "Number of loads PRE'd" | |||
| ) |
|
static |
Referenced by IsValueFullyAvailableInBlock().
1.8.6