mirror of
https://github.com/intel/llvm.git
synced 2026-02-09 01:52:26 +08:00
[MS Compat] Add support for __declspec(noalias)
The attribute '__declspec(noalias)' communicates that the function only accesses memory pointed to by its pointer-typed arguments. llvm-svn: 242728
This commit is contained in:
@@ -867,6 +867,12 @@ def ReturnsTwice : InheritableAttr {
|
||||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
def NoAlias : InheritableAttr {
|
||||
let Spellings = [Declspec<"noalias">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [NoAliasDocs];
|
||||
}
|
||||
|
||||
def NoCommon : InheritableAttr {
|
||||
let Spellings = [GCC<"nocommon">];
|
||||
let Subjects = SubjectList<[Var]>;
|
||||
|
||||
@@ -1583,3 +1583,13 @@ The ``returns_nonnull`` attribute indicates that a particular function (or Objec
|
||||
The ``returns_nonnull`` attribute implies that returning a null pointer is undefined behavior, which the optimizer may take advantage of. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable
|
||||
}];
|
||||
}
|
||||
|
||||
def NoAliasDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "noalias";
|
||||
let Content = [{
|
||||
The ``noalias`` attribute indicates that the only memory accesses inside
|
||||
function are loads and stores from objects pointed to by its pointer-typed
|
||||
arguments, with arbitrary offsets.
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -1421,13 +1421,16 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
|
||||
FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
|
||||
}
|
||||
|
||||
// 'const' and 'pure' attribute functions are also nounwind.
|
||||
// 'const', 'pure' and 'noalias' attributed functions are also nounwind.
|
||||
if (TargetDecl->hasAttr<ConstAttr>()) {
|
||||
FuncAttrs.addAttribute(llvm::Attribute::ReadNone);
|
||||
FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
|
||||
} else if (TargetDecl->hasAttr<PureAttr>()) {
|
||||
FuncAttrs.addAttribute(llvm::Attribute::ReadOnly);
|
||||
FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
|
||||
} else if (TargetDecl->hasAttr<NoAliasAttr>()) {
|
||||
FuncAttrs.addAttribute(llvm::Attribute::ArgMemOnly);
|
||||
FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
|
||||
}
|
||||
if (TargetDecl->hasAttr<RestrictAttr>())
|
||||
RetAttrs.addAttribute(llvm::Attribute::NoAlias);
|
||||
|
||||
@@ -4723,6 +4723,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
||||
case AttributeList::AT_Mode:
|
||||
handleModeAttr(S, D, Attr);
|
||||
break;
|
||||
case AttributeList::AT_NoAlias:
|
||||
handleSimpleAttribute<NoAliasAttr>(S, D, Attr);
|
||||
break;
|
||||
case AttributeList::AT_NoCommon:
|
||||
handleSimpleAttribute<NoCommonAttr>(S, D, Attr);
|
||||
break;
|
||||
|
||||
@@ -33,7 +33,12 @@ __declspec(noinline) void t2() {}
|
||||
__declspec(noreturn) void f20_t(void);
|
||||
void f20(void) { f20_t(); }
|
||||
|
||||
__declspec(noalias) void noalias_callee(int *x);
|
||||
// CHECK: call void @noalias_callee({{.*}}) [[NA:#[0-9]+]]
|
||||
void noalias_caller(int *x) { noalias_callee(x); }
|
||||
|
||||
// CHECK: attributes [[NAKED]] = { naked noinline nounwind{{.*}} }
|
||||
// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
|
||||
// CHECK: attributes [[NI]] = { noinline nounwind{{.*}} }
|
||||
// CHECK: attributes [[NR]] = { noreturn }
|
||||
// CHECK: attributes [[NA]] = { nounwind argmemonly{{.*}} }
|
||||
|
||||
@@ -5,7 +5,7 @@ typedef int (__cdecl *tptr)(void);
|
||||
void (*__fastcall fastpfunc)(void);
|
||||
extern __declspec(dllimport) void __stdcall VarR4FromDec(void);
|
||||
__declspec(deprecated) __declspec(deprecated) char * __cdecl ltoa( long _Val, char * _DstBuf, int _Radix);
|
||||
__declspec(safebuffers) __declspec(noalias) __declspec(restrict) void * __cdecl xxx(void *_Memory); /* expected-warning{{__declspec attribute 'safebuffers' is not supported}} expected-warning{{__declspec attribute 'noalias' is not supported}} */
|
||||
__declspec(safebuffers) __declspec(noalias) __declspec(restrict) void * __cdecl xxx(void *_Memory); /* expected-warning{{__declspec attribute 'safebuffers' is not supported}} */
|
||||
typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR;
|
||||
|
||||
void * __ptr64 PtrToPtr64(const void *p) {
|
||||
|
||||
Reference in New Issue
Block a user