mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-11 07:18:44 +00:00
This patch addresses two cleanup issues:
1. Verify::VerifyParameterAttrs in "lib/IR/Verifier.cpp" and AttrBuilder::removeFunctionOnlyAttrs in "lib/IR/Attributes.cpp" (only called by Verify::VerifyFunctionAttrs) separately maintained a list of function-only attribute types. I've consolidated the logic into a new function used for both cases in "lib/IR/Verifier.cpp", so this logic is in one place (other than the AsmParser front-end) 2. Various functions in "lib/IR/Verifier.cpp" passed AttributeSet around by reference needlessly, as it's just a handle to an immutable pimpl body. Patch by Stephen Lin! llvm-svn: 179790
This commit is contained in:
parent
ad7b3011a6
commit
480edeaf79
@ -474,9 +474,6 @@ public:
|
||||
|
||||
bool td_empty() const { return TargetDepAttrs.empty(); }
|
||||
|
||||
/// \brief Remove attributes that are used on functions only.
|
||||
void removeFunctionOnlyAttrs();
|
||||
|
||||
bool operator==(const AttrBuilder &B);
|
||||
bool operator!=(const AttrBuilder &B) {
|
||||
return !(*this == B);
|
||||
|
@ -1115,33 +1115,6 @@ bool AttrBuilder::operator==(const AttrBuilder &B) {
|
||||
return Alignment == B.Alignment && StackAlignment == B.StackAlignment;
|
||||
}
|
||||
|
||||
void AttrBuilder::removeFunctionOnlyAttrs() {
|
||||
removeAttribute(Attribute::NoReturn)
|
||||
.removeAttribute(Attribute::NoUnwind)
|
||||
.removeAttribute(Attribute::ReadNone)
|
||||
.removeAttribute(Attribute::ReadOnly)
|
||||
.removeAttribute(Attribute::NoInline)
|
||||
.removeAttribute(Attribute::AlwaysInline)
|
||||
.removeAttribute(Attribute::OptimizeForSize)
|
||||
.removeAttribute(Attribute::StackProtect)
|
||||
.removeAttribute(Attribute::StackProtectReq)
|
||||
.removeAttribute(Attribute::StackProtectStrong)
|
||||
.removeAttribute(Attribute::NoRedZone)
|
||||
.removeAttribute(Attribute::NoImplicitFloat)
|
||||
.removeAttribute(Attribute::Naked)
|
||||
.removeAttribute(Attribute::InlineHint)
|
||||
.removeAttribute(Attribute::StackAlignment)
|
||||
.removeAttribute(Attribute::UWTable)
|
||||
.removeAttribute(Attribute::NonLazyBind)
|
||||
.removeAttribute(Attribute::ReturnsTwice)
|
||||
.removeAttribute(Attribute::SanitizeAddress)
|
||||
.removeAttribute(Attribute::SanitizeThread)
|
||||
.removeAttribute(Attribute::SanitizeMemory)
|
||||
.removeAttribute(Attribute::MinSize)
|
||||
.removeAttribute(Attribute::NoDuplicate)
|
||||
.removeAttribute(Attribute::NoBuiltin);
|
||||
}
|
||||
|
||||
AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) {
|
||||
// FIXME: Remove this in 4.0.
|
||||
if (!Val) return *this;
|
||||
|
@ -301,9 +301,12 @@ namespace {
|
||||
bool VerifyIntrinsicType(Type *Ty,
|
||||
ArrayRef<Intrinsic::IITDescriptor> &Infos,
|
||||
SmallVectorImpl<Type*> &ArgTys);
|
||||
void VerifyParameterAttrs(AttributeSet Attrs, uint64_t Idx, Type *Ty,
|
||||
bool VerifyAttributeCount(AttributeSet Attrs, unsigned Params);
|
||||
void VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx,
|
||||
bool isFunction, const Value *V);
|
||||
void VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
|
||||
bool isReturnValue, const Value *V);
|
||||
void VerifyFunctionAttrs(FunctionType *FT, const AttributeSet &Attrs,
|
||||
void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
|
||||
const Value *V);
|
||||
|
||||
void WriteValue(const Value *V) {
|
||||
@ -626,37 +629,66 @@ void Verifier::visitModuleFlag(MDNode *Op, DenseMap<MDString*, MDNode*>&SeenIDs,
|
||||
}
|
||||
}
|
||||
|
||||
void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx,
|
||||
bool isFunction, const Value* V) {
|
||||
unsigned Slot = ~0U;
|
||||
for (unsigned I = 0, E = Attrs.getNumSlots(); I != E; ++I)
|
||||
if (Attrs.getSlotIndex(I) == Idx) {
|
||||
Slot = I;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(Slot != ~0U && "Attribute set inconsistency!");
|
||||
|
||||
for (AttributeSet::iterator I = Attrs.begin(Slot), E = Attrs.end(Slot);
|
||||
I != E; ++I) {
|
||||
if (I->isStringAttribute())
|
||||
continue;
|
||||
|
||||
if (I->getKindAsEnum() == Attribute::NoReturn ||
|
||||
I->getKindAsEnum() == Attribute::NoUnwind ||
|
||||
I->getKindAsEnum() == Attribute::ReadNone ||
|
||||
I->getKindAsEnum() == Attribute::ReadOnly ||
|
||||
I->getKindAsEnum() == Attribute::NoInline ||
|
||||
I->getKindAsEnum() == Attribute::AlwaysInline ||
|
||||
I->getKindAsEnum() == Attribute::OptimizeForSize ||
|
||||
I->getKindAsEnum() == Attribute::StackProtect ||
|
||||
I->getKindAsEnum() == Attribute::StackProtectReq ||
|
||||
I->getKindAsEnum() == Attribute::StackProtectStrong ||
|
||||
I->getKindAsEnum() == Attribute::NoRedZone ||
|
||||
I->getKindAsEnum() == Attribute::NoImplicitFloat ||
|
||||
I->getKindAsEnum() == Attribute::Naked ||
|
||||
I->getKindAsEnum() == Attribute::InlineHint ||
|
||||
I->getKindAsEnum() == Attribute::StackAlignment ||
|
||||
I->getKindAsEnum() == Attribute::UWTable ||
|
||||
I->getKindAsEnum() == Attribute::NonLazyBind ||
|
||||
I->getKindAsEnum() == Attribute::ReturnsTwice ||
|
||||
I->getKindAsEnum() == Attribute::SanitizeAddress ||
|
||||
I->getKindAsEnum() == Attribute::SanitizeThread ||
|
||||
I->getKindAsEnum() == Attribute::SanitizeMemory ||
|
||||
I->getKindAsEnum() == Attribute::MinSize ||
|
||||
I->getKindAsEnum() == Attribute::NoDuplicate ||
|
||||
I->getKindAsEnum() == Attribute::NoBuiltin) {
|
||||
if (!isFunction)
|
||||
CheckFailed("Attribute '" + I->getKindAsString() +
|
||||
"' only applies to functions!", V);
|
||||
return;
|
||||
} else if (isFunction) {
|
||||
CheckFailed("Attribute '" + I->getKindAsString() +
|
||||
"' does not apply to functions!", V);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyParameterAttrs - Check the given attributes for an argument or return
|
||||
// value of the specified type. The value V is printed in error messages.
|
||||
void Verifier::VerifyParameterAttrs(AttributeSet Attrs, uint64_t Idx, Type *Ty,
|
||||
void Verifier::VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
|
||||
bool isReturnValue, const Value *V) {
|
||||
if (!Attrs.hasAttributes(Idx))
|
||||
return;
|
||||
|
||||
Assert1(!Attrs.hasAttribute(Idx, Attribute::NoReturn) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::NoUnwind) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::ReadNone) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::ReadOnly) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::NoInline) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::AlwaysInline) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::OptimizeForSize) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::StackProtect) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::StackProtectReq) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::NoRedZone) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::NoImplicitFloat) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::Naked) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::InlineHint) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::StackAlignment) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::UWTable) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::NonLazyBind) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::ReturnsTwice) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::SanitizeAddress) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::SanitizeThread) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::SanitizeMemory) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::MinSize) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::NoBuiltin),
|
||||
"Some attributes in '" + Attrs.getAsString(Idx) +
|
||||
"' only apply to functions!", V);
|
||||
VerifyAttributeTypes(Attrs, Idx, false, V);
|
||||
|
||||
if (isReturnValue)
|
||||
Assert1(!Attrs.hasAttribute(Idx, Attribute::ByVal) &&
|
||||
@ -712,8 +744,7 @@ void Verifier::VerifyParameterAttrs(AttributeSet Attrs, uint64_t Idx, Type *Ty,
|
||||
|
||||
// VerifyFunctionAttrs - Check parameter attributes against a function type.
|
||||
// The value V is printed in error messages.
|
||||
void Verifier::VerifyFunctionAttrs(FunctionType *FT,
|
||||
const AttributeSet &Attrs,
|
||||
void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
|
||||
const Value *V) {
|
||||
if (Attrs.isEmpty())
|
||||
return;
|
||||
@ -721,72 +752,31 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT,
|
||||
bool SawNest = false;
|
||||
|
||||
for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) {
|
||||
unsigned Index = Attrs.getSlotIndex(i);
|
||||
unsigned Idx = Attrs.getSlotIndex(i);
|
||||
|
||||
Type *Ty;
|
||||
if (Index == 0)
|
||||
if (Idx == 0)
|
||||
Ty = FT->getReturnType();
|
||||
else if (Index-1 < FT->getNumParams())
|
||||
Ty = FT->getParamType(Index-1);
|
||||
else if (Idx-1 < FT->getNumParams())
|
||||
Ty = FT->getParamType(Idx-1);
|
||||
else
|
||||
break; // VarArgs attributes, verified elsewhere.
|
||||
|
||||
VerifyParameterAttrs(Attrs, Index, Ty, Index == 0, V);
|
||||
VerifyParameterAttrs(Attrs, Idx, Ty, Idx == 0, V);
|
||||
|
||||
if (Attrs.hasAttribute(i, Attribute::Nest)) {
|
||||
Assert1(!SawNest, "More than one parameter has attribute nest!", V);
|
||||
SawNest = true;
|
||||
}
|
||||
|
||||
if (Attrs.hasAttribute(Index, Attribute::StructRet))
|
||||
Assert1(Index == 1, "Attribute sret is not on first parameter!", V);
|
||||
if (Attrs.hasAttribute(Idx, Attribute::StructRet))
|
||||
Assert1(Idx == 1, "Attribute sret is not on first parameter!", V);
|
||||
}
|
||||
|
||||
if (!Attrs.hasAttributes(AttributeSet::FunctionIndex))
|
||||
return;
|
||||
|
||||
AttrBuilder NotFn(Attrs, AttributeSet::FunctionIndex);
|
||||
NotFn.removeFunctionOnlyAttrs();
|
||||
Assert1(NotFn.empty(), "Attributes '" +
|
||||
AttributeSet::get(V->getContext(),
|
||||
AttributeSet::FunctionIndex,
|
||||
NotFn).getAsString(AttributeSet::FunctionIndex) +
|
||||
"' do not apply to the function!", V);
|
||||
|
||||
// Check for mutually incompatible attributes.
|
||||
Assert1(!((Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::ByVal) &&
|
||||
Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::Nest)) ||
|
||||
(Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::ByVal) &&
|
||||
Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::StructRet)) ||
|
||||
(Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::Nest) &&
|
||||
Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::StructRet))),
|
||||
"Attributes 'byval, nest, and sret' are incompatible!", V);
|
||||
|
||||
Assert1(!((Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::ByVal) &&
|
||||
Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::Nest)) ||
|
||||
(Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::ByVal) &&
|
||||
Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::InReg)) ||
|
||||
(Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::Nest) &&
|
||||
Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::InReg))),
|
||||
"Attributes 'byval, nest, and inreg' are incompatible!", V);
|
||||
|
||||
Assert1(!(Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::ZExt) &&
|
||||
Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::SExt)),
|
||||
"Attributes 'zeroext and signext' are incompatible!", V);
|
||||
VerifyAttributeTypes(Attrs, AttributeSet::FunctionIndex, true, V);
|
||||
|
||||
Assert1(!(Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::ReadNone) &&
|
||||
@ -801,7 +791,7 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT,
|
||||
"Attributes 'noinline and alwaysinline' are incompatible!", V);
|
||||
}
|
||||
|
||||
static bool VerifyAttributeCount(const AttributeSet &Attrs, unsigned Params) {
|
||||
bool Verifier::VerifyAttributeCount(AttributeSet Attrs, unsigned Params) {
|
||||
if (Attrs.getNumSlots() == 0)
|
||||
return true;
|
||||
|
||||
@ -837,7 +827,7 @@ void Verifier::visitFunction(Function &F) {
|
||||
Assert1(!F.hasStructRetAttr() || F.getReturnType()->isVoidTy(),
|
||||
"Invalid struct return type!", &F);
|
||||
|
||||
const AttributeSet &Attrs = F.getAttributes();
|
||||
AttributeSet Attrs = F.getAttributes();
|
||||
|
||||
Assert1(VerifyAttributeCount(Attrs, FT->getNumParams()),
|
||||
"Attribute after last parameter!", &F);
|
||||
@ -1350,7 +1340,7 @@ void Verifier::VerifyCallSite(CallSite CS) {
|
||||
"Call parameter type does not match function signature!",
|
||||
CS.getArgument(i), FTy->getParamType(i), I);
|
||||
|
||||
const AttributeSet &Attrs = CS.getAttributes();
|
||||
AttributeSet Attrs = CS.getAttributes();
|
||||
|
||||
Assert1(VerifyAttributeCount(Attrs, CS.arg_size()),
|
||||
"Attribute after last parameter!", I);
|
||||
|
Loading…
x
Reference in New Issue
Block a user