mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[Attributes] Clean up handling of UB implying attributes (NFC)
Rather than adding methods for dropping these attributes in various places, add a function that returns an AttrBuilder with these attributes, which can then be used with existing methods for dropping attributes. This is with an eye on D104641, which also needs to drop them from returns, not just parameters. Also be more explicit about the semantics of the method in the documentation. Refer to UB rather than Undef, which is what this is actually about.
This commit is contained in:
parent
adc5107b73
commit
ed5a269ff1
@ -546,12 +546,6 @@ public:
|
|||||||
return removeAttributes(C, ArgNo + FirstArgIndex, AttrsToRemove);
|
return removeAttributes(C, ArgNo + FirstArgIndex, AttrsToRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove noundef attribute and other attributes that imply undefined
|
|
||||||
/// behavior if a `undef` or `poison` value is passed from this attribute
|
|
||||||
/// list. Returns a new list because attribute lists are immutable.
|
|
||||||
LLVM_NODISCARD AttributeList
|
|
||||||
removeParamUndefImplyingAttributes(LLVMContext &C, unsigned ArgNo) const;
|
|
||||||
|
|
||||||
/// Remove all attributes at the specified arg index from this
|
/// Remove all attributes at the specified arg index from this
|
||||||
/// attribute list. Returns a new list because attribute lists are immutable.
|
/// attribute list. Returns a new list because attribute lists are immutable.
|
||||||
LLVM_NODISCARD AttributeList removeParamAttributes(LLVMContext &C,
|
LLVM_NODISCARD AttributeList removeParamAttributes(LLVMContext &C,
|
||||||
@ -1038,6 +1032,13 @@ namespace AttributeFuncs {
|
|||||||
/// Which attributes cannot be applied to a type.
|
/// Which attributes cannot be applied to a type.
|
||||||
AttrBuilder typeIncompatible(Type *Ty);
|
AttrBuilder typeIncompatible(Type *Ty);
|
||||||
|
|
||||||
|
/// Get param/return attributes which imply immediate undefined behavior if an
|
||||||
|
/// invalid value is passed. For example, this includes noundef (where undef
|
||||||
|
/// implies UB), but not nonnull (where null implies poison). It also does not
|
||||||
|
/// include attributes like nocapture, which constrain the function
|
||||||
|
/// implementation rather than the passed value.
|
||||||
|
AttrBuilder getUBImplyingAttributes();
|
||||||
|
|
||||||
/// \returns Return true if the two functions have compatible target-independent
|
/// \returns Return true if the two functions have compatible target-independent
|
||||||
/// attributes for inlining purposes.
|
/// attributes for inlining purposes.
|
||||||
bool areInlineCompatible(const Function &Caller, const Function &Callee);
|
bool areInlineCompatible(const Function &Caller, const Function &Callee);
|
||||||
|
@ -1558,15 +1558,6 @@ public:
|
|||||||
setAttributes(PAL);
|
setAttributes(PAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes noundef and other attributes that imply undefined behavior if a
|
|
||||||
/// `undef` or `poison` value is passed from the given argument.
|
|
||||||
void removeParamUndefImplyingAttrs(unsigned ArgNo) {
|
|
||||||
assert(ArgNo < getNumArgOperands() && "Out of bounds");
|
|
||||||
AttributeList PAL = getAttributes();
|
|
||||||
PAL = PAL.removeParamUndefImplyingAttributes(getContext(), ArgNo);
|
|
||||||
setAttributes(PAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// adds the dereferenceable attribute to the list of attributes.
|
/// adds the dereferenceable attribute to the list of attributes.
|
||||||
void addDereferenceableAttr(unsigned i, uint64_t Bytes) {
|
void addDereferenceableAttr(unsigned i, uint64_t Bytes) {
|
||||||
AttributeList PAL = getAttributes();
|
AttributeList PAL = getAttributes();
|
||||||
|
@ -1335,16 +1335,6 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C,
|
|||||||
return getImpl(C, AttrSets);
|
return getImpl(C, AttrSets);
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeList
|
|
||||||
AttributeList::removeParamUndefImplyingAttributes(LLVMContext &C,
|
|
||||||
unsigned ArgNo) const {
|
|
||||||
AttrBuilder B;
|
|
||||||
B.addAttribute(Attribute::NoUndef);
|
|
||||||
B.addDereferenceableAttr(1);
|
|
||||||
B.addDereferenceableOrNullAttr(1);
|
|
||||||
return removeParamAttributes(C, ArgNo, B);
|
|
||||||
}
|
|
||||||
|
|
||||||
AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C,
|
AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C,
|
||||||
unsigned Index,
|
unsigned Index,
|
||||||
uint64_t Bytes) const {
|
uint64_t Bytes) const {
|
||||||
@ -1926,6 +1916,14 @@ AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
|
|||||||
return Incompatible;
|
return Incompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AttrBuilder AttributeFuncs::getUBImplyingAttributes() {
|
||||||
|
AttrBuilder B;
|
||||||
|
B.addAttribute(Attribute::NoUndef);
|
||||||
|
B.addDereferenceableAttr(1);
|
||||||
|
B.addDereferenceableOrNullAttr(1);
|
||||||
|
return B;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename AttrClass>
|
template<typename AttrClass>
|
||||||
static bool isEqual(const Function &Caller, const Function &Callee) {
|
static bool isEqual(const Function &Caller, const Function &Callee) {
|
||||||
return Caller.getFnAttribute(AttrClass::getKind()) ==
|
return Caller.getFnAttribute(AttrClass::getKind()) ==
|
||||||
|
@ -601,12 +601,6 @@ void Function::removeParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs) {
|
|||||||
setAttributes(PAL);
|
setAttributes(PAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Function::removeParamUndefImplyingAttrs(unsigned ArgNo) {
|
|
||||||
AttributeList PAL = getAttributes();
|
|
||||||
PAL = PAL.removeParamUndefImplyingAttributes(getContext(), ArgNo);
|
|
||||||
setAttributes(PAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Function::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
|
void Function::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
|
||||||
AttributeList PAL = getAttributes();
|
AttributeList PAL = getAttributes();
|
||||||
PAL = PAL.addDereferenceableAttr(getContext(), i, Bytes);
|
PAL = PAL.addDereferenceableAttr(getContext(), i, Bytes);
|
||||||
|
@ -287,6 +287,7 @@ bool DeadArgumentEliminationPass::RemoveDeadArgumentsFromCallers(Function &Fn) {
|
|||||||
SmallVector<unsigned, 8> UnusedArgs;
|
SmallVector<unsigned, 8> UnusedArgs;
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
|
|
||||||
|
AttrBuilder UBImplyingAttributes = AttributeFuncs::getUBImplyingAttributes();
|
||||||
for (Argument &Arg : Fn.args()) {
|
for (Argument &Arg : Fn.args()) {
|
||||||
if (!Arg.hasSwiftErrorAttr() && Arg.use_empty() &&
|
if (!Arg.hasSwiftErrorAttr() && Arg.use_empty() &&
|
||||||
!Arg.hasPassPointeeByValueCopyAttr()) {
|
!Arg.hasPassPointeeByValueCopyAttr()) {
|
||||||
@ -295,7 +296,7 @@ bool DeadArgumentEliminationPass::RemoveDeadArgumentsFromCallers(Function &Fn) {
|
|||||||
Changed = true;
|
Changed = true;
|
||||||
}
|
}
|
||||||
UnusedArgs.push_back(Arg.getArgNo());
|
UnusedArgs.push_back(Arg.getArgNo());
|
||||||
Fn.removeParamUndefImplyingAttrs(Arg.getArgNo());
|
Fn.removeParamAttrs(Arg.getArgNo(), UBImplyingAttributes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +314,7 @@ bool DeadArgumentEliminationPass::RemoveDeadArgumentsFromCallers(Function &Fn) {
|
|||||||
|
|
||||||
Value *Arg = CB->getArgOperand(ArgNo);
|
Value *Arg = CB->getArgOperand(ArgNo);
|
||||||
CB->setArgOperand(ArgNo, UndefValue::get(Arg->getType()));
|
CB->setArgOperand(ArgNo, UndefValue::get(Arg->getType()));
|
||||||
CB->removeParamUndefImplyingAttrs(ArgNo);
|
CB->removeParamAttrs(ArgNo, UBImplyingAttributes);
|
||||||
|
|
||||||
++NumArgumentsReplacedWithUndef;
|
++NumArgumentsReplacedWithUndef;
|
||||||
Changed = true;
|
Changed = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user