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<unsigned, SmallVector<Instruction *, 32>>;
+
+ /// 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<Instruction *>;
+
+ /// 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<const Function *, OpcodeInstMapTy>;
+
+ /// A map type from functions to their read or write instructions.
+ using FuncRWInstsMapTy = DenseMap<const Function *, InstructionVectorTy>;
+
+ /// 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
const Function &F, const llvm::function_ref<bool(Instruction &)> &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.
///{
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<unsigned, SmallVector<Instruction *, 32>>;
-
- /// 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<Instruction *>;
-
- /// 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<const Function *, OpcodeInstMapTy>;
-
- /// A map type from functions to their read or write instructions.
- using FuncRWInstsMapTy = DenseMap<const Function *, InstructionVectorTy>;
-
- /// 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
std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> Pred =
[&](Value &RV, const SmallPtrSetImpl<ReturnInst *> &RetInsts) -> bool {
- Function &F = getAnchorScope();
- if (isKnownNonZero(&RV, F.getParent()->getDataLayout()))
+ if (isKnownNonZero(&RV, A.getDataLayout()))
return true;
auto *NonNullAA = A.getAAFor<AANonNull>(*this, RV);
CallSite CS(&getAnchorValue());
if (CS.paramHasAttr(getArgNo(), getAttrKind()) ||
CS.paramHasAttr(getArgNo(), Attribute::Dereferenceable) ||
- isKnownNonZero(getAssociatedValue(),
- getAnchorScope().getParent()->getDataLayout()))
+ isKnownNonZero(getAssociatedValue(), A.getDataLayout()))
indicateOptimisticFixpoint();
}
return true;
Value *V = CS.getArgOperand(ArgNo);
- if (isKnownNonZero(V, getAnchorScope().getParent()->getDataLayout()))
+ if (isKnownNonZero(V, A.getDataLayout()))
return true;
return false;
}
// 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);
takeAssumedMinimum(AlignAA->getAssumedAlign());
else
// Use IR information.
- takeAssumedMinimum(RV.getPointerAlignment(
- getAnchorScope().getParent()->getDataLayout()));
+ takeAssumedMinimum(RV.getPointerAlignment(A.getDataLayout()));
return isValidState();
};
Argument &Arg = cast<Argument>(getAnchorValue());
unsigned ArgNo = Arg.getArgNo();
- const DataLayout &DL = F.getParent()->getDataLayout();
+ const DataLayout &DL = A.getDataLayout();
auto BeforeState = getAssumed();
/// 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).