/// sufficient to determine where arguments will be manifested. This is, so
/// far, only the case for call site arguments as the value is not sufficient
/// to pinpoint them. Instead, we can use the call site as an anchor.
- ///
- ///{
- Value &getAnchorValue() {
+ Value &getAnchorValue() const {
assert(KindOrArgNo != IRP_INVALID &&
"Invalid position does not have an anchor value!");
return *AnchorVal;
}
- const Value &getAnchorValue() const {
- return const_cast<IRPosition *>(this)->getAnchorValue();
- }
- ///}
/// Return the associated function, if any.
- ///
- ///{
- Function *getAssociatedFunction() {
+ Function *getAssociatedFunction() const {
if (auto *CB = dyn_cast<CallBase>(AnchorVal))
return CB->getCalledFunction();
assert(KindOrArgNo != IRP_INVALID &&
return cast<Instruction>(V).getFunction();
return nullptr;
}
- const Function *getAssociatedFunction() const {
- return const_cast<IRPosition *>(this)->getAssociatedFunction();
- }
- ///}
/// Return the associated argument, if any.
- ///
- ///{
- Argument *getAssociatedArgument() {
+ Argument *getAssociatedArgument() const {
if (auto *Arg = dyn_cast<Argument>(&getAnchorValue()))
return Arg;
int ArgNo = getArgNo();
return nullptr;
return AssociatedFn->arg_begin() + ArgNo;
}
- const Argument *getAssociatedArgument() const {
- return const_cast<IRPosition *>(this)->getAssociatedArgument();
- }
- ///}
/// Return true if the position refers to a function interface, that is the
/// function scope, the function return, or an argumnt.
}
/// Return the Function surrounding the anchor value.
- ///
- ///{
- Function *getAnchorScope() {
+ Function *getAnchorScope() const {
Value &V = getAnchorValue();
if (isa<Function>(V))
return &cast<Function>(V);
return cast<Instruction>(V).getFunction();
return nullptr;
}
- const Function *getAnchorScope() const {
- return const_cast<IRPosition *>(this)->getAnchorScope();
- }
- ///}
/// Return the context instruction, if any.
- ///
- ///{
- Instruction *getCtxI() {
+ Instruction *getCtxI() const {
Value &V = getAnchorValue();
if (auto *I = dyn_cast<Instruction>(&V))
return I;
return &(F->getEntryBlock().front());
return nullptr;
}
- const Instruction *getCtxI() const {
- return const_cast<IRPosition *>(this)->getCtxI();
- }
- ///}
/// Return the value this abstract attribute is associated with.
- ///
- ///{
- Value &getAssociatedValue() {
+ Value &getAssociatedValue() const {
assert(KindOrArgNo != IRP_INVALID &&
"Invalid position does not have an associated value!");
if (getArgNo() < 0 || isa<Argument>(AnchorVal))
assert(isa<CallBase>(AnchorVal) && "Expected a call base!");
return *cast<CallBase>(AnchorVal)->getArgOperand(getArgNo());
}
- const Value &getAssociatedValue() const {
- return const_cast<IRPosition *>(this)->getAssociatedValue();
- }
- ///}
/// Return the argument number of the associated value if it is an argument or
/// call site argument, otherwise a negative value.
}
/// Remove the attribute of kind \p AKs existing in the IR at this position.
- void removeAttrs(ArrayRef<Attribute::AttrKind> AKs) {
+ void removeAttrs(ArrayRef<Attribute::AttrKind> AKs) const {
if (getPositionKind() == IRP_INVALID || getPositionKind() == IRP_FLOAT)
return;
/// Verify internal invariants.
void verify();
+protected:
/// The value this position is anchored at.
Value *AnchorVal;
"'AbstractAttribute'!");
// Put the attribute in the lookup map structure and the container we use to
// keep track of all attributes.
- IRPosition &IRP = AA.getIRPosition();
+ const IRPosition &IRP = AA.getIRPosition();
auto &KindToAbstractAttributeMap = AAMap[IRP];
assert(!KindToAbstractAttributeMap.count(&AAType::ID) &&
"Attribute already in map!");
/// Helper struct necessary as the modular build fails if the virtual method
/// IRAttribute::manifest is defined in the Attributor.cpp.
struct IRAttributeManifest {
- static ChangeStatus manifestAttrs(Attributor &A, IRPosition &IRP,
+ static ChangeStatus manifestAttrs(Attributor &A, const IRPosition &IRP,
const ArrayRef<Attribute> &DeducedAttrs);
};
}
/// Return an IR position, see struct IRPosition.
- ///
- ///{
- IRPosition &getIRPosition() override { return *this; }
const IRPosition &getIRPosition() const override { return *this; }
- ///}
};
/// Base struct for all "concrete attribute" deductions.
/// add statistics for them.
virtual void trackStatistics() const = 0;
- /// Return an IR position, see struct IRPosition.
- virtual IRPosition &getIRPosition() = 0;
-
/// The actual update/transfer function which has to be implemented by the
/// derived classes.
///
}
/// Return an IR position, see struct IRPosition.
- ///
- ///{
- IRPosition &getIRPosition() override { return *this; }
const IRPosition &getIRPosition() const override { return *this; }
- ///}
/// Create an abstract attribute view for the position \p IRP.
static AAIsDead &createForPosition(const IRPosition &IRP, Attributor &A);
AAValueSimplify(const IRPosition &IRP) : IRPosition(IRP) {}
/// Return an IR position, see struct IRPosition.
- ///
- ///{
- IRPosition &getIRPosition() { return *this; }
const IRPosition &getIRPosition() const { return *this; }
- ///}
/// Return an assumed simplified value if a single candidate is found. If
/// there cannot be one, return original value. If it is not clear yet, return
bool isKnownHeapToStack() const { return getKnown(); }
/// Return an IR position, see struct IRPosition.
- ///
- ///{
- IRPosition &getIRPosition() { return *this; }
const IRPosition &getIRPosition() const { return *this; }
- ///}
/// Create an abstract attribute view for the position \p IRP.
static AAHeapToStack &createForPosition(const IRPosition &IRP, Attributor &A);
}
ChangeStatus
-IRAttributeManifest::manifestAttrs(Attributor &A, IRPosition &IRP,
+IRAttributeManifest::manifestAttrs(Attributor &A, const IRPosition &IRP,
const ArrayRef<Attribute> &DeducedAttrs) {
Function *ScopeFn = IRP.getAssociatedFunction();
IRPosition::Kind PK = IRP.getPositionKind();
void initialize(Attributor &A) override {
Base::initialize(A);
- IRPosition &IRP = this->getIRPosition();
+ const IRPosition &IRP = this->getIRPosition();
Instruction *CtxI = IRP.getCtxI();
if (!CtxI)
// If the assumed unique return value is an argument, annotate it.
if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
- getIRPosition() = IRPosition::argument(*UniqueRVArg);
+ // TODO: This should be handled differently!
+ this->AnchorVal = UniqueRVArg;
+ this->KindOrArgNo = UniqueRVArg->getArgNo();
Changed = IRAttribute::manifest(A);
} else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
// We can replace the returned value with the unique returned constant.
/// See AbstractAttribute::manifest(...).
ChangeStatus manifest(Attributor &A) override {
- IRPosition &IRP = getIRPosition();
+ const IRPosition &IRP = getIRPosition();
// Check if we would improve the existing attributes first.
SmallVector<Attribute, 4> DeducedAttrs;