diff options
author | Stanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com> | 2017-03-17 23:56:58 +0000 |
---|---|---|
committer | Stanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com> | 2017-03-17 23:56:58 +0000 |
commit | 8e45acfc3884a89d776c5c850c71ae80f645db99 (patch) | |
tree | 95921e0e002d02af2b40d193b8447cef8cd5642f /llvm/lib | |
parent | 0f5063c7547ec908318471fb3d58ed4461ee0a8f (diff) | |
download | bcm5719-llvm-8e45acfc3884a89d776c5c850c71ae80f645db99.tar.gz bcm5719-llvm-8e45acfc3884a89d776c5c850c71ae80f645db99.zip |
[AMDGPU] Add address space based alias analysis pass
This is direct port of HSAILAliasAnalysis pass, just cleaned for
style and renamed.
Differential Revision: https://reviews.llvm.org/D31103
llvm-svn: 298172
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPU.h | 3 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp | 117 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.h | 86 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/CMakeLists.txt | 1 |
5 files changed, 223 insertions, 0 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.h b/llvm/lib/Target/AMDGPU/AMDGPU.h index 3e269fad71f..1cc68c7e242 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPU.h +++ b/llvm/lib/Target/AMDGPU/AMDGPU.h @@ -119,6 +119,9 @@ extern char &SIDebuggerInsertNopsID; void initializeSIInsertWaitsPass(PassRegistry&); extern char &SIInsertWaitsID; +ImmutablePass *createAMDGPUAAWrapperPass(); +void initializeAMDGPUAAWrapperPassPass(PassRegistry&); + Target &getTheAMDGPUTarget(); Target &getTheGCNTarget(); diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp new file mode 100644 index 00000000000..127b2639794 --- /dev/null +++ b/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp @@ -0,0 +1,117 @@ +//===- AMDGPUAliasAnalysis ---------------------------------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This is the AMGPU address space based alias analysis pass. +//===----------------------------------------------------------------------===// + +#include "AMDGPU.h" +#include "AMDGPUAliasAnalysis.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/Analysis/Passes.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" + +using namespace llvm; + +#define DEBUG_TYPE "amdgpu-aa" + +// Register this pass... +char AMDGPUAAWrapperPass::ID = 0; +INITIALIZE_PASS(AMDGPUAAWrapperPass, "amdgpu-aa", + "AMDGPU Address space based Alias Analysis", false, true) + +ImmutablePass *llvm::createAMDGPUAAWrapperPass() { + return new AMDGPUAAWrapperPass(); +} + +void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); +} + +AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) { + // This array is indexed by the AMDGPUAS::AddressSpaces + // enum elements PRIVATE_ADDRESS ... to FLAT_ADDRESS + // see "llvm/Transforms/AMDSPIRUtils.h" + static const AliasResult ASAliasRules[5][5] = { + /* Private Global Constant Group Flat */ + /* Private */ {MayAlias, NoAlias , NoAlias , NoAlias , MayAlias}, + /* Global */ {NoAlias , MayAlias, NoAlias , NoAlias , MayAlias}, + /* Constant */ {NoAlias , NoAlias , MayAlias, NoAlias , MayAlias}, + /* Group */ {NoAlias , NoAlias , NoAlias , MayAlias, MayAlias}, + /* Flat */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias} + }; + unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace(); + unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace(); + if (asA > AMDGPUAS::AddressSpaces::FLAT_ADDRESS || + asB > AMDGPUAS::AddressSpaces::FLAT_ADDRESS) + report_fatal_error("Pointer address space out of range"); + + AliasResult Result = ASAliasRules[asA][asB]; + if (Result == NoAlias) return Result; + + if (isa<Argument>(LocA.Ptr) && isa<Argument>(LocB.Ptr)) { + Type *T1 = cast<PointerType>(LocA.Ptr->getType())->getElementType(); + Type *T2 = cast<PointerType>(LocB.Ptr->getType())->getElementType(); + + if ((T1->isVectorTy() && !T2->isVectorTy()) || + (T2->isVectorTy() && !T1->isVectorTy())) + return NoAlias; + } + // Forward the query to the next alias analysis. + return AAResultBase::alias(LocA, LocB); +} + +bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc, + bool OrLocal) { + const Value *Base = GetUnderlyingObject(Loc.Ptr, DL); + + if (Base->getType()->getPointerAddressSpace() == + AMDGPUAS::AddressSpaces::CONSTANT_ADDRESS) { + return true; + } + + if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) { + if (GV->isConstant()) + return true; + } else if (const Argument *Arg = dyn_cast<Argument>(Base)) { + const Function *F = Arg->getParent(); + + // Only assume constant memory for arguments on kernels. + switch (F->getCallingConv()) { + default: + return AAResultBase::pointsToConstantMemory(Loc, OrLocal); + case CallingConv::AMDGPU_VS: + case CallingConv::AMDGPU_GS: + case CallingConv::AMDGPU_PS: + case CallingConv::AMDGPU_CS: + case CallingConv::AMDGPU_KERNEL: + case CallingConv::SPIR_KERNEL: + break; + } + + unsigned ArgNo = Arg->getArgNo(); + /* On an argument, ReadOnly attribute indicates that the function does + not write through this pointer argument, even though it may write + to the memory that the pointer points to. + On an argument, ReadNone attribute indicates that the function does + not dereference that pointer argument, even though it may read or write + the memory that the pointer points to if accessed through other pointers. + */ + if (F->getAttributes().hasAttribute(ArgNo + 1, Attribute::NoAlias) && + (F->getAttributes().hasAttribute(ArgNo + 1, Attribute::ReadNone) || + F->getAttributes().hasAttribute(ArgNo + 1, Attribute::ReadOnly))) { + return true; + } + } + return AAResultBase::pointsToConstantMemory(Loc, OrLocal); +} diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.h b/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.h new file mode 100644 index 00000000000..943b4a68b25 --- /dev/null +++ b/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.h @@ -0,0 +1,86 @@ +//===- AMDGPUAliasAnalysis ---------------------------------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This is the AMGPU address space based alias analysis pass. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_AMDGPUALIASANALYSIS_H +#define LLVM_ANALYSIS_AMDGPUALIASANALYSIS_H + +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" + +namespace llvm { + +/// A simple AA result that uses TBAA metadata to answer queries. +class AMDGPUAAResult : public AAResultBase<AMDGPUAAResult> { + friend AAResultBase<AMDGPUAAResult>; + + const DataLayout &DL; + +public: + explicit AMDGPUAAResult(const DataLayout &DL) : AAResultBase(), DL(DL) {} + AMDGPUAAResult(AMDGPUAAResult &&Arg) + : AAResultBase(std::move(Arg)), DL(Arg.DL){} + + /// Handle invalidation events from the new pass manager. + /// + /// By definition, this result is stateless and so remains valid. + bool invalidate(Function &, const PreservedAnalyses &) { return false; } + + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); + bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal); + +private: + bool Aliases(const MDNode *A, const MDNode *B) const; + bool PathAliases(const MDNode *A, const MDNode *B) const; +}; + +/// Analysis pass providing a never-invalidated alias analysis result. +class AMDGPUAA : public AnalysisInfoMixin<AMDGPUAA> { + friend AnalysisInfoMixin<AMDGPUAA>; + static char PassID; + +public: + typedef AMDGPUAAResult Result; + + AMDGPUAAResult run(Function &F, AnalysisManager<Function> &AM) { + return AMDGPUAAResult(F.getParent()->getDataLayout()); + } +}; + +/// Legacy wrapper pass to provide the AMDGPUAAResult object. +class AMDGPUAAWrapperPass : public ImmutablePass { + std::unique_ptr<AMDGPUAAResult> Result; + +public: + static char ID; + + AMDGPUAAWrapperPass() : ImmutablePass(ID) { + initializeAMDGPUAAWrapperPassPass(*PassRegistry::getPassRegistry()); + } + + AMDGPUAAResult &getResult() { return *Result; } + const AMDGPUAAResult &getResult() const { return *Result; } + + bool doInitialization(Module &M) override { + Result.reset(new AMDGPUAAResult(M.getDataLayout())); + return false; + } + bool doFinalization(Module &M) override { + Result.reset(); + return false; + } + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + +} +#endif // LLVM_ANALYSIS_AMDGPUALIASANALYSIS_H diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index 48442bcf2f1..33ba0883e30 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -15,6 +15,7 @@ #include "AMDGPUTargetMachine.h" #include "AMDGPU.h" +#include "AMDGPUAliasAnalysis.h" #include "AMDGPUCallLowering.h" #include "AMDGPUInstructionSelector.h" #include "AMDGPULegalizerInfo.h" @@ -93,6 +94,11 @@ static cl::opt<bool> InternalizeSymbols( cl::init(false), cl::Hidden); +// Enable address space based alias analysis +static cl::opt<bool> EnableAMDGPUAliasAnalysis("enable-amdgpu-aa", cl::Hidden, + cl::desc("Enable AMDGPU Alias Analysis"), + cl::init(true)); + extern "C" void LLVMInitializeAMDGPUTarget() { // Register the target RegisterTargetMachine<R600TargetMachine> X(getTheAMDGPUTarget()); @@ -119,6 +125,7 @@ extern "C" void LLVMInitializeAMDGPUTarget() { initializeSIInsertSkipsPass(*PR); initializeSIDebuggerInsertNopsPass(*PR); initializeSIOptimizeExecMaskingPass(*PR); + initializeAMDGPUAAWrapperPassPass(*PR); } static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) { @@ -507,6 +514,15 @@ void AMDGPUPassConfig::addIRPasses() { addPass(createSROAPass()); addStraightLineScalarOptimizationPasses(); + + if (EnableAMDGPUAliasAnalysis) { + addPass(createAMDGPUAAWrapperPass()); + addPass(createExternalAAWrapperPass([](Pass &P, Function &, + AAResults &AAR) { + if (auto *WrapperPass = P.getAnalysisIfAvailable<AMDGPUAAWrapperPass>()) + AAR.addAAResult(WrapperPass->getResult()); + })); + } } TargetPassConfig::addIRPasses(); diff --git a/llvm/lib/Target/AMDGPU/CMakeLists.txt b/llvm/lib/Target/AMDGPU/CMakeLists.txt index a1c263c8764..7b550e8f2b5 100644 --- a/llvm/lib/Target/AMDGPU/CMakeLists.txt +++ b/llvm/lib/Target/AMDGPU/CMakeLists.txt @@ -36,6 +36,7 @@ endif() add_llvm_target(AMDGPUCodeGen AMDILCFGStructurizer.cpp + AMDGPUAliasAnalysis.cpp AMDGPUAlwaysInlinePass.cpp AMDGPUAnnotateKernelFeatures.cpp AMDGPUAnnotateUniformValues.cpp |