diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h index 402f6a6263e0..6e1aabd4463e 100644 --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -119,6 +119,60 @@ ChangeStatus operator|(ChangeStatus l, ChangeStatus r); ChangeStatus operator&(ChangeStatus l, ChangeStatus r); ///} +/// Data structure to hold cached (LLVM-IR) information. +/// +/// All attributes are given an InformationCache object at creation time to +/// avoid inspection of the IR by all of them individually. This default +/// InformationCache will hold information required by 'default' attributes, +/// thus the ones deduced when Attributor::identifyDefaultAbstractAttributes(..) +/// is called. +/// +/// If custom abstract attributes, registered manually through +/// Attributor::registerAA(...), need more information, especially if it is not +/// reusable, it is advised to inherit from the InformationCache and cast the +/// instance down in the abstract attributes. +struct InformationCache { + InformationCache(const DataLayout &DL) : DL(DL) {} + + /// A map type from opcodes to instructions with this opcode. + using OpcodeInstMapTy = DenseMap>; + + /// Return the map that relates "interesting" opcodes with all instructions + /// with that opcode in \p F. + OpcodeInstMapTy &getOpcodeInstMapForFunction(const Function &F) { + return FuncInstOpcodeMap[&F]; + } + + /// A vector type to hold instructions. + using InstructionVectorTy = std::vector; + + /// Return the instructions in \p F that may read or write memory. + InstructionVectorTy &getReadOrWriteInstsForFunction(const Function &F) { + return FuncRWInstsMap[&F]; + } + +private: + /// A map type from functions to opcode to instruction maps. + using FuncInstOpcodeMapTy = DenseMap; + + /// A map type from functions to their read or write instructions. + using FuncRWInstsMapTy = DenseMap; + + /// A nested map that remembers all instructions in a function with a certain + /// instruction opcode (Instruction::getOpcode()). + FuncInstOpcodeMapTy FuncInstOpcodeMap; + + /// A map from functions to their instructions that may read or write memory. + FuncRWInstsMapTy FuncRWInstsMap; + + /// The datalayout used in the module. + const DataLayout &DL; + + /// Give the Attributor access to the members so + /// Attributor::identifyDefaultAbstractAttributes(...) can initialize them. + friend struct Attributor; +}; + /// The fixpoint analysis framework that orchestrates the attribute deduction. /// /// The Attributor provides a general abstract analysis framework (guided @@ -320,6 +374,9 @@ struct Attributor { const Function &F, const llvm::function_ref &Pred, AbstractAttribute &QueryingAA); + /// Return the data layout associated with the anchor scope. + const DataLayout &getDataLayout() const { return InfoCache.DL; } + private: /// The set of all abstract attributes. ///{ @@ -348,60 +405,6 @@ private: InformationCache &InfoCache; }; -/// Data structure to hold cached (LLVM-IR) information. -/// -/// All attributes are given an InformationCache object at creation time to -/// avoid inspection of the IR by all of them individually. This default -/// InformationCache will hold information required by 'default' attributes, -/// thus the ones deduced when Attributor::identifyDefaultAbstractAttributes(..) -/// is called. -/// -/// If custom abstract attributes, registered manually through -/// Attributor::registerAA(...), need more information, especially if it is not -/// reusable, it is advised to inherit from the InformationCache and cast the -/// instance down in the abstract attributes. -struct InformationCache { - InformationCache(const DataLayout &DL) : DL(DL) {} - - /// A map type from opcodes to instructions with this opcode. - using OpcodeInstMapTy = DenseMap>; - - /// Return the map that relates "interesting" opcodes with all instructions - /// with that opcode in \p F. - OpcodeInstMapTy &getOpcodeInstMapForFunction(const Function &F) { - return FuncInstOpcodeMap[&F]; - } - - /// A vector type to hold instructions. - using InstructionVectorTy = std::vector; - - /// Return the instructions in \p F that may read or write memory. - InstructionVectorTy &getReadOrWriteInstsForFunction(const Function &F) { - return FuncRWInstsMap[&F]; - } - -private: - /// A map type from functions to opcode to instruction maps. - using FuncInstOpcodeMapTy = DenseMap; - - /// A map type from functions to their read or write instructions. - using FuncRWInstsMapTy = DenseMap; - - /// A nested map that remembers all instructions in a function with a certain - /// instruction opcode (Instruction::getOpcode()). - FuncInstOpcodeMapTy FuncInstOpcodeMap; - - /// A map from functions to their instructions that may read or write memory. - FuncRWInstsMapTy FuncRWInstsMap; - - /// The datalayout used in the module. - const DataLayout &DL; - - /// Give the Attributor access to the members so - /// Attributor::identifyDefaultAbstractAttributes(...) can initialize them. - friend struct Attributor; -}; - /// An interface to query the internal state of an abstract attribute. /// /// The abstract state is a minimal interface that allows the Attributor to diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 40a0c2657a73..ba7626276c85 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -941,9 +941,8 @@ AANonNullImpl::generatePredicate(Attributor &A) { std::function &)> Pred = [&](Value &RV, const SmallPtrSetImpl &RetInsts) -> bool { - Function &F = getAnchorScope(); - if (isKnownNonZero(&RV, F.getParent()->getDataLayout())) + if (isKnownNonZero(&RV, A.getDataLayout())) return true; auto *NonNullAA = A.getAAFor(*this, RV); @@ -1026,8 +1025,7 @@ struct AANonNullCallSiteArgument final : AANonNullImpl { CallSite CS(&getAnchorValue()); if (CS.paramHasAttr(getArgNo(), getAttrKind()) || CS.paramHasAttr(getArgNo(), Attribute::Dereferenceable) || - isKnownNonZero(getAssociatedValue(), - getAnchorScope().getParent()->getDataLayout())) + isKnownNonZero(getAssociatedValue(), A.getDataLayout())) indicateOptimisticFixpoint(); } @@ -1063,7 +1061,7 @@ ChangeStatus AANonNullArgument::updateImpl(Attributor &A) { return true; Value *V = CS.getArgOperand(ArgNo); - if (isKnownNonZero(V, getAnchorScope().getParent()->getDataLayout())) + if (isKnownNonZero(V, A.getDataLayout())) return true; return false; @@ -1700,7 +1698,7 @@ uint64_t AADereferenceableImpl::computeAssumedDerefenceableBytes( } // Otherwise, we try to compute assumed bytes from base pointer. - const DataLayout &DL = getAnchorScope().getParent()->getDataLayout(); + const DataLayout &DL = A.getDataLayout(); unsigned IdxWidth = DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace()); APInt Offset(IdxWidth, 0); @@ -1918,8 +1916,7 @@ ChangeStatus AAAlignReturned::updateImpl(Attributor &A) { takeAssumedMinimum(AlignAA->getAssumedAlign()); else // Use IR information. - takeAssumedMinimum(RV.getPointerAlignment( - getAnchorScope().getParent()->getDataLayout())); + takeAssumedMinimum(RV.getPointerAlignment(A.getDataLayout())); return isValidState(); }; @@ -1948,7 +1945,7 @@ ChangeStatus AAAlignArgument::updateImpl(Attributor &A) { Argument &Arg = cast(getAnchorValue()); unsigned ArgNo = Arg.getArgNo(); - const DataLayout &DL = F.getParent()->getDataLayout(); + const DataLayout &DL = A.getDataLayout(); auto BeforeState = getAssumed(); @@ -1986,8 +1983,8 @@ struct AAAlignCallSiteArgument final : AAAlignImpl { /// See AbstractAttribute::initialize(...). void initialize(Attributor &A) override { CallSite CS(&getAnchorValue()); - takeKnownMaximum(getAssociatedValue()->getPointerAlignment( - getAnchorScope().getParent()->getDataLayout())); + takeKnownMaximum( + getAssociatedValue()->getPointerAlignment(A.getDataLayout())); } /// See AbstractAttribute::updateImpl(Attributor &A).