diff options
Diffstat (limited to 'lib/Target/R600/AMDGPUPromoteAlloca.cpp')
-rw-r--r-- | lib/Target/R600/AMDGPUPromoteAlloca.cpp | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/lib/Target/R600/AMDGPUPromoteAlloca.cpp b/lib/Target/R600/AMDGPUPromoteAlloca.cpp index 218750d445e6..b81fef47d55a 100644 --- a/lib/Target/R600/AMDGPUPromoteAlloca.cpp +++ b/lib/Target/R600/AMDGPUPromoteAlloca.cpp @@ -36,11 +36,9 @@ class AMDGPUPromoteAlloca : public FunctionPass, public: AMDGPUPromoteAlloca(const AMDGPUSubtarget &st) : FunctionPass(ID), ST(st), LocalMemAvailable(0) { } - virtual bool doInitialization(Module &M); - virtual bool runOnFunction(Function &F); - virtual const char *getPassName() const { - return "AMDGPU Promote Alloca"; - } + bool doInitialization(Module &M) override; + bool runOnFunction(Function &F) override; + const char *getPassName() const override { return "AMDGPU Promote Alloca"; } void visitAlloca(AllocaInst &I); }; @@ -107,14 +105,16 @@ static VectorType *arrayTypeToVecType(const Type *ArrayTy) { ArrayTy->getArrayNumElements()); } -static Value* calculateVectorIndex(Value *Ptr, - std::map<GetElementPtrInst*, Value*> GEPIdx) { +static Value * +calculateVectorIndex(Value *Ptr, + const std::map<GetElementPtrInst *, Value *> &GEPIdx) { if (isa<AllocaInst>(Ptr)) return Constant::getNullValue(Type::getInt32Ty(Ptr->getContext())); GetElementPtrInst *GEP = cast<GetElementPtrInst>(Ptr); - return GEPIdx[GEP]; + auto I = GEPIdx.find(GEP); + return I == GEPIdx.end() ? nullptr : I->second; } static Value* GEPToVectorIndex(GetElementPtrInst *GEP) { @@ -234,7 +234,8 @@ static bool tryPromoteAllocaToVector(AllocaInst *Alloca) { return true; } -static void collectUsesWithPtrTypes(Value *Val, std::vector<Value*> &WorkList) { +static bool collectUsesWithPtrTypes(Value *Val, std::vector<Value*> &WorkList) { + bool Success = true; for (User *User : Val->users()) { if(std::find(WorkList.begin(), WorkList.end(), User) != WorkList.end()) continue; @@ -242,11 +243,20 @@ static void collectUsesWithPtrTypes(Value *Val, std::vector<Value*> &WorkList) { WorkList.push_back(User); continue; } + + // FIXME: Correctly handle ptrtoint instructions. + Instruction *UseInst = dyn_cast<Instruction>(User); + if (UseInst && UseInst->getOpcode() == Instruction::PtrToInt) + return false; + if (!User->getType()->isPointerTy()) continue; + WorkList.push_back(User); - collectUsesWithPtrTypes(User, WorkList); + + Success &= collectUsesWithPtrTypes(User, WorkList); } + return Success; } void AMDGPUPromoteAlloca::visitAlloca(AllocaInst &I) { @@ -274,6 +284,13 @@ void AMDGPUPromoteAlloca::visitAlloca(AllocaInst &I) { return; } + std::vector<Value*> WorkList; + + if (!collectUsesWithPtrTypes(&I, WorkList)) { + DEBUG(dbgs() << " Do not know how to convert all uses\n"); + return; + } + DEBUG(dbgs() << "Promoting alloca to local memory\n"); LocalMemAvailable -= AllocaSize; @@ -320,10 +337,6 @@ void AMDGPUPromoteAlloca::visitAlloca(AllocaInst &I) { I.replaceAllUsesWith(Offset); I.eraseFromParent(); - std::vector<Value*> WorkList; - - collectUsesWithPtrTypes(Offset, WorkList); - for (std::vector<Value*>::iterator i = WorkList.begin(), e = WorkList.end(); i != e; ++i) { Value *V = *i; @@ -331,6 +344,13 @@ void AMDGPUPromoteAlloca::visitAlloca(AllocaInst &I) { if (!Call) { Type *EltTy = V->getType()->getPointerElementType(); PointerType *NewTy = PointerType::get(EltTy, AMDGPUAS::LOCAL_ADDRESS); + + // The operand's value should be corrected on its own. + if (isa<AddrSpaceCastInst>(V)) + continue; + + // FIXME: It doesn't really make sense to try to do this for all + // instructions. V->mutateType(NewTy); continue; } |