#include "AMDGPU.h"
#include "GCNSubtarget.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/UniformityAnalysis.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/InitializePasses.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#define DEBUG_TYPE …
usingnamespacellvm;
usingnamespacellvm::AMDGPU;
namespace {
struct ReplacementInfo { … };
class AMDGPUAtomicOptimizer : public FunctionPass { … };
class AMDGPUAtomicOptimizerImpl
: public InstVisitor<AMDGPUAtomicOptimizerImpl> { … };
}
char AMDGPUAtomicOptimizer::ID = …;
char &llvm::AMDGPUAtomicOptimizerID = …;
bool AMDGPUAtomicOptimizer::runOnFunction(Function &F) { … }
PreservedAnalyses AMDGPUAtomicOptimizerPass::run(Function &F,
FunctionAnalysisManager &AM) { … }
bool AMDGPUAtomicOptimizerImpl::run(Function &F) { … }
static bool isLegalCrossLaneType(Type *Ty) { … }
void AMDGPUAtomicOptimizerImpl::visitAtomicRMWInst(AtomicRMWInst &I) { … }
void AMDGPUAtomicOptimizerImpl::visitIntrinsicInst(IntrinsicInst &I) { … }
static Value *buildNonAtomicBinOp(IRBuilder<> &B, AtomicRMWInst::BinOp Op,
Value *LHS, Value *RHS) { … }
Value *AMDGPUAtomicOptimizerImpl::buildReduction(IRBuilder<> &B,
AtomicRMWInst::BinOp Op,
Value *V,
Value *const Identity) const { … }
Value *AMDGPUAtomicOptimizerImpl::buildScan(IRBuilder<> &B,
AtomicRMWInst::BinOp Op, Value *V,
Value *Identity) const { … }
Value *AMDGPUAtomicOptimizerImpl::buildShiftRight(IRBuilder<> &B, Value *V,
Value *Identity) const { … }
std::pair<Value *, Value *> AMDGPUAtomicOptimizerImpl::buildScanIteratively(
IRBuilder<> &B, AtomicRMWInst::BinOp Op, Value *const Identity, Value *V,
Instruction &I, BasicBlock *ComputeLoop, BasicBlock *ComputeEnd) const { … }
static Constant *getIdentityValueForAtomicOp(Type *const Ty,
AtomicRMWInst::BinOp Op) { … }
static Value *buildMul(IRBuilder<> &B, Value *LHS, Value *RHS) { … }
void AMDGPUAtomicOptimizerImpl::optimizeAtomic(Instruction &I,
AtomicRMWInst::BinOp Op,
unsigned ValIdx,
bool ValDivergent) const { … }
INITIALIZE_PASS_BEGIN(AMDGPUAtomicOptimizer, DEBUG_TYPE,
"AMDGPU atomic optimizations", false, false)
INITIALIZE_PASS_DEPENDENCY(UniformityInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_END(AMDGPUAtomicOptimizer, DEBUG_TYPE,
"AMDGPU atomic optimizations", false, false)
FunctionPass *llvm::createAMDGPUAtomicOptimizerPass(ScanOptions ScanStrategy) { … }