diff options
Diffstat (limited to 'lib/Transforms/Scalar/InferAddressSpaces.cpp')
-rw-r--r-- | lib/Transforms/Scalar/InferAddressSpaces.cpp | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/lib/Transforms/Scalar/InferAddressSpaces.cpp b/lib/Transforms/Scalar/InferAddressSpaces.cpp index fbbc09eb487f..5f0e2001c73d 100644 --- a/lib/Transforms/Scalar/InferAddressSpaces.cpp +++ b/lib/Transforms/Scalar/InferAddressSpaces.cpp @@ -1,9 +1,8 @@ //===- InferAddressSpace.cpp - --------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -149,7 +148,9 @@ class InferAddressSpaces : public FunctionPass { public: static char ID; - InferAddressSpaces() : FunctionPass(ID) {} + InferAddressSpaces() : + FunctionPass(ID), FlatAddrSpace(UninitializedAddressSpace) {} + InferAddressSpaces(unsigned AS) : FunctionPass(ID), FlatAddrSpace(AS) {} void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); @@ -218,13 +219,17 @@ static bool isAddressExpression(const Value &V) { if (!isa<Operator>(V)) return false; - switch (cast<Operator>(V).getOpcode()) { + const Operator &Op = cast<Operator>(V); + switch (Op.getOpcode()) { case Instruction::PHI: + assert(Op.getType()->isPointerTy()); + return true; case Instruction::BitCast: case Instruction::AddrSpaceCast: case Instruction::GetElementPtr: - case Instruction::Select: return true; + case Instruction::Select: + return Op.getType()->isPointerTy(); default: return false; } @@ -548,10 +553,17 @@ static Value *cloneConstantExprWithNewAddressSpace( if (Value *NewOperand = ValueWithNewAddrSpace.lookup(Operand)) { IsNew = true; NewOperands.push_back(cast<Constant>(NewOperand)); - } else { - // Otherwise, reuses the old operand. - NewOperands.push_back(Operand); + continue; } + if (auto CExpr = dyn_cast<ConstantExpr>(Operand)) + if (Value *NewOperand = cloneConstantExprWithNewAddressSpace( + CExpr, NewAddrSpace, ValueWithNewAddrSpace)) { + IsNew = true; + NewOperands.push_back(cast<Constant>(NewOperand)); + continue; + } + // Otherwise, reuses the old operand. + NewOperands.push_back(Operand); } // If !IsNew, we will replace the Value with itself. However, replaced values @@ -621,9 +633,12 @@ bool InferAddressSpaces::runOnFunction(Function &F) { const TargetTransformInfo &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F); - FlatAddrSpace = TTI.getFlatAddressSpace(); - if (FlatAddrSpace == UninitializedAddressSpace) - return false; + + if (FlatAddrSpace == UninitializedAddressSpace) { + FlatAddrSpace = TTI.getFlatAddressSpace(); + if (FlatAddrSpace == UninitializedAddressSpace) + return false; + } // Collects all flat address expressions in postorder. std::vector<WeakTrackingVH> Postorder = collectFlatAddressExpressions(F); @@ -991,8 +1006,12 @@ bool InferAddressSpaces::rewriteWithNewAddressSpaces( } // Otherwise, replaces the use with flat(NewV). - if (Instruction *I = dyn_cast<Instruction>(V)) { - BasicBlock::iterator InsertPos = std::next(I->getIterator()); + if (Instruction *Inst = dyn_cast<Instruction>(V)) { + // Don't create a copy of the original addrspacecast. + if (U == V && isa<AddrSpaceCastInst>(V)) + continue; + + BasicBlock::iterator InsertPos = std::next(Inst->getIterator()); while (isa<PHINode>(InsertPos)) ++InsertPos; U.set(new AddrSpaceCastInst(NewV, V->getType(), "", &*InsertPos)); @@ -1015,6 +1034,6 @@ bool InferAddressSpaces::rewriteWithNewAddressSpaces( return true; } -FunctionPass *llvm::createInferAddressSpacesPass() { - return new InferAddressSpaces(); +FunctionPass *llvm::createInferAddressSpacesPass(unsigned AddressSpace) { + return new InferAddressSpaces(AddressSpace); } |