X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FR600%2FAMDGPUPromoteAlloca.cpp;h=b81fef47d55a3241a407c49adc100a4af06aa255;hb=6e6318f148c2293673d94b040e298354360d6a35;hp=053ea8a90b77ab6a793e7cbbffc1bb7f69a61f38;hpb=20e4c0d24e2dded15f99d7d658d679fd5b55cdc3;p=oota-llvm.git diff --git a/lib/Target/R600/AMDGPUPromoteAlloca.cpp b/lib/Target/R600/AMDGPUPromoteAlloca.cpp index 053ea8a90b7..b81fef47d55 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 GEPIdx) { +static Value * +calculateVectorIndex(Value *Ptr, + const std::map &GEPIdx) { if (isa(Ptr)) return Constant::getNullValue(Type::getInt32Ty(Ptr->getContext())); GetElementPtrInst *GEP = cast(Ptr); - return GEPIdx[GEP]; + auto I = GEPIdx.find(GEP); + return I == GEPIdx.end() ? nullptr : I->second; } static Value* GEPToVectorIndex(GetElementPtrInst *GEP) { @@ -129,6 +129,22 @@ static Value* GEPToVectorIndex(GetElementPtrInst *GEP) { return GEP->getOperand(2); } +// Not an instruction handled below to turn into a vector. +// +// TODO: Check isTriviallyVectorizable for calls and handle other +// instructions. +static bool canVectorizeInst(Instruction *Inst) { + switch (Inst->getOpcode()) { + case Instruction::Load: + case Instruction::Store: + case Instruction::BitCast: + case Instruction::AddrSpaceCast: + return true; + default: + return false; + } +} + static bool tryPromoteAllocaToVector(AllocaInst *Alloca) { Type *AllocaTy = Alloca->getAllocatedType(); @@ -149,6 +165,9 @@ static bool tryPromoteAllocaToVector(AllocaInst *Alloca) { for (User *AllocaUser : Alloca->users()) { GetElementPtrInst *GEP = dyn_cast(AllocaUser); if (!GEP) { + if (!canVectorizeInst(cast(AllocaUser))) + return false; + WorkList.push_back(AllocaUser); continue; } @@ -164,6 +183,9 @@ static bool tryPromoteAllocaToVector(AllocaInst *Alloca) { GEPVectorIdx[GEP] = Index; for (User *GEPUser : AllocaUser->users()) { + if (!canVectorizeInst(cast(GEPUser))) + return false; + WorkList.push_back(GEPUser); } } @@ -201,18 +223,19 @@ static bool tryPromoteAllocaToVector(AllocaInst *Alloca) { break; } case Instruction::BitCast: + case Instruction::AddrSpaceCast: break; default: Inst->dump(); - llvm_unreachable("Do not know how to replace this instruction " - "with vector op"); + llvm_unreachable("Inconsistency in instructions promotable to vector"); } } return true; } -static void collectUsesWithPtrTypes(Value *Val, std::vector &WorkList) { +static bool collectUsesWithPtrTypes(Value *Val, std::vector &WorkList) { + bool Success = true; for (User *User : Val->users()) { if(std::find(WorkList.begin(), WorkList.end(), User) != WorkList.end()) continue; @@ -220,11 +243,20 @@ static void collectUsesWithPtrTypes(Value *Val, std::vector &WorkList) { WorkList.push_back(User); continue; } + + // FIXME: Correctly handle ptrtoint instructions. + Instruction *UseInst = dyn_cast(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) { @@ -252,6 +284,13 @@ void AMDGPUPromoteAlloca::visitAlloca(AllocaInst &I) { return; } + std::vector 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; @@ -298,10 +337,6 @@ void AMDGPUPromoteAlloca::visitAlloca(AllocaInst &I) { I.replaceAllUsesWith(Offset); I.eraseFromParent(); - std::vector WorkList; - - collectUsesWithPtrTypes(Offset, WorkList); - for (std::vector::iterator i = WorkList.begin(), e = WorkList.end(); i != e; ++i) { Value *V = *i; @@ -309,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(V)) + continue; + + // FIXME: It doesn't really make sense to try to do this for all + // instructions. V->mutateType(NewTy); continue; }