From d932679c71c0a650c0afa109d4fdcbbe0e48877b Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 11 Nov 2015 20:35:42 +0000 Subject: [PATCH] Move the enum attributes defined in Attributes.h to a table-gen file. This is a step towards consolidating some of the information regarding attributes in a single place. This patch moves the enum attributes in Attributes.h to the table-gen file. Additionally, it adds definitions of target independent string attributes that will be used in follow-up commits by the inliner to check attribute compatibility. rdar://problem/19836465 llvm-svn: 252796 --- llvm/include/llvm/IR/Attributes.h | 57 +-------- llvm/include/llvm/IR/Attributes.td | 160 +++++++++++++++++++++++++ llvm/include/llvm/IR/CMakeLists.txt | 5 +- llvm/lib/IR/Makefile | 18 ++- llvm/utils/TableGen/Attributes.cpp | 59 +++++++++ llvm/utils/TableGen/CMakeLists.txt | 1 + llvm/utils/TableGen/TableGen.cpp | 8 +- llvm/utils/TableGen/TableGenBackends.h | 1 + 8 files changed, 250 insertions(+), 59 deletions(-) create mode 100644 llvm/include/llvm/IR/Attributes.td create mode 100644 llvm/utils/TableGen/Attributes.cpp diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h index 1e95e908dba7..52a9ca83013b 100644 --- a/llvm/include/llvm/IR/Attributes.h +++ b/llvm/include/llvm/IR/Attributes.h @@ -64,61 +64,8 @@ public: enum AttrKind { // IR-Level Attributes None, ///< No attributes have been set - Alignment, ///< Alignment of parameter (5 bits) - ///< stored as log2 of alignment with +1 bias - ///< 0 means unaligned (different from align(1)) - AlwaysInline, ///< inline=always - ArgMemOnly, ///< Funciton can access memory only using pointers - ///< based on its arguments. - Builtin, ///< Callee is recognized as a builtin, despite - ///< nobuiltin attribute on its declaration. - ByVal, ///< Pass structure by value - Cold, ///< Marks function as being in a cold path. - Convergent, ///< Can only be moved to control-equivalent blocks - Dereferenceable, ///< Pointer is known to be dereferenceable - DereferenceableOrNull, ///< Pointer is either null or dereferenceable - InAlloca, ///< Pass structure in an alloca - InlineHint, ///< Source said inlining was desirable - InReg, ///< Force argument to be passed in register - JumpTable, ///< Build jump-instruction tables and replace refs. - MinSize, ///< Function must be optimized for size first - Naked, ///< Naked function - Nest, ///< Nested function static chain - NoAlias, ///< Considered to not alias after call - NoBuiltin, ///< Callee isn't recognized as a builtin - NoCapture, ///< Function creates no aliases of pointer - NoDuplicate, ///< Call cannot be duplicated - NoImplicitFloat, ///< Disable implicit floating point insts - NoInline, ///< inline=never - NonLazyBind, ///< Function is called early and/or - ///< often, so lazy binding isn't worthwhile - NonNull, ///< Pointer is known to be not null - NoRecurse, ///< The function does not recurse - NoRedZone, ///< Disable redzone - NoReturn, ///< Mark the function as not returning - NoUnwind, ///< Function doesn't unwind stack - OptimizeForSize, ///< opt_size - OptimizeNone, ///< Function must not be optimized. - ReadNone, ///< Function does not access memory - ReadOnly, ///< Function only reads from memory - Returned, ///< Return value is always equal to this argument - ReturnsTwice, ///< Function can return twice - SafeStack, ///< Safe Stack protection. - SanitizeAddress, ///< AddressSanitizer is on. - SanitizeMemory, ///< MemorySanitizer is on. - SanitizeThread, ///< ThreadSanitizer is on. - SExt, ///< Sign extended before/after call - StackAlignment, ///< Alignment of stack for function (3 bits) - ///< stored as log2 of alignment with +1 bias 0 - ///< means unaligned (different from - ///< alignstack=(1)) - StackProtect, ///< Stack protection. - StackProtectReq, ///< Stack protection required. - StackProtectStrong, ///< Strong Stack protection. - StructRet, ///< Hidden pointer to structure to return - UWTable, ///< Function must be in a unwind table - ZExt, ///< Zero extended before/after call - + #define GET_ATTR_ENUM + #include "llvm/IR/Attributes.inc" EndAttrKinds ///< Sentinal value useful for loops }; diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td new file mode 100644 index 000000000000..5ba76ef34904 --- /dev/null +++ b/llvm/include/llvm/IR/Attributes.td @@ -0,0 +1,160 @@ +/// Attribute base class. +class Attr { + // String representation of this attribute in the IR. + string AttrString = S; +} + +/// Enum attribute. +class EnumAttr : Attr; + +/// StringBool attribute. +class StrBoolAttr : Attr; + +/// Target-independent enum attributes. + +/// Alignment of parameter (5 bits) stored as log2 of alignment with +1 bias. +/// 0 means unaligned (different from align(1)). +def Alignment : EnumAttr<"align">; + +/// inline=always. +def AlwaysInline : EnumAttr<"alwaysinline">; + +/// Funciton can access memory only using pointers based on its arguments. +def ArgMemOnly : EnumAttr<"argmemonly">; + +/// Callee is recognized as a builtin, despite nobuiltin attribute on its +/// declaration. +def Builtin : EnumAttr<"builtin">; + +/// Pass structure by value. +def ByVal : EnumAttr<"byval">; + +/// Marks function as being in a cold path. +def Cold : EnumAttr<"cold">; + +/// Can only be moved to control-equivalent blocks. +def Convergent : EnumAttr<"convergent">; + +/// Pointer is known to be dereferenceable. +def Dereferenceable : EnumAttr<"dereferenceable">; + +/// Pointer is either null or dereferenceable. +def DereferenceableOrNull : EnumAttr<"dereferenceable_or_null">; + +/// Pass structure in an alloca. +def InAlloca : EnumAttr<"inalloca">; + +/// Source said inlining was desirable. +def InlineHint : EnumAttr<"inlinehint">; + +/// Force argument to be passed in register. +def InReg : EnumAttr<"inreg">; + +/// Build jump-instruction tables and replace refs. +def JumpTable : EnumAttr<"jumptable">; + +/// Function must be optimized for size first. +def MinSize : EnumAttr<"minsize">; + +/// Naked function. +def Naked : EnumAttr<"naked">; + +/// Nested function static chain. +def Nest : EnumAttr<"nest">; + +/// Considered to not alias after call. +def NoAlias : EnumAttr<"noalias">; + +/// Callee isn't recognized as a builtin. +def NoBuiltin : EnumAttr<"nobuiltin">; + +/// Function creates no aliases of pointer. +def NoCapture : EnumAttr<"nocapture">; + +/// Call cannot be duplicated. +def NoDuplicate : EnumAttr<"noduplicate">; + +/// Disable implicit floating point insts. +def NoImplicitFloat : EnumAttr<"noimplicitfloat">; + +/// inline=never. +def NoInline : EnumAttr<"noinline">; + +/// Function is called early and/or often, so lazy binding isn't worthwhile. +def NonLazyBind : EnumAttr<"nonlazybind">; + +/// Pointer is known to be not null. +def NonNull : EnumAttr<"nonnull">; + +/// The function does not recurse. +def NoRecurse : EnumAttr<"norecurse">; + +/// Disable redzone. +def NoRedZone : EnumAttr<"noredzone">; + +/// Mark the function as not returning. +def NoReturn : EnumAttr<"noreturn">; + +/// Function doesn't unwind stack. +def NoUnwind : EnumAttr<"nounwind">; + +/// opt_size. +def OptimizeForSize : EnumAttr<"optsize">; + +/// Function must not be optimized. +def OptimizeNone : EnumAttr<"optnone">; + +/// Function does not access memory. +def ReadNone : EnumAttr<"readnone">; + +/// Function only reads from memory. +def ReadOnly : EnumAttr<"readonly">; + +/// Return value is always equal to this argument. +def Returned : EnumAttr<"returned">; + +/// Function can return twice. +def ReturnsTwice : EnumAttr<"returns_twice">; + +/// Safe Stack protection. +def SafeStack : EnumAttr<"safestack">; + +/// Sign extended before/after call. +def SExt : EnumAttr<"signext">; + +/// Alignment of stack for function (3 bits) stored as log2 of alignment with +/// +1 bias 0 means unaligned (different from alignstack=(1)). +def StackAlignment : EnumAttr<"alignstack">; + +/// Stack protection. +def StackProtect : EnumAttr<"ssp">; + +/// Stack protection required. +def StackProtectReq : EnumAttr<"sspreq">; + +/// Strong Stack protection. +def StackProtectStrong : EnumAttr<"sspstrong">; + +/// Hidden pointer to structure to return. +def StructRet : EnumAttr<"sret">; + +/// AddressSanitizer is on. +def SanitizeAddress : EnumAttr<"sanitize_address">; + +/// ThreadSanitizer is on. +def SanitizeThread : EnumAttr<"sanitize_thread">; + +/// MemorySanitizer is on. +def SanitizeMemory : EnumAttr<"sanitize_memory">; + +/// Function must be in a unwind table. +def UWTable : EnumAttr<"uwtable">; + +/// Zero extended before/after call. +def ZExt : EnumAttr<"zeroext">; + +/// Target-independent string attributes. +def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">; +def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">; +def NoNansFPMath : StrBoolAttr<"no-nans-fp-math">; +def UnsafeFPMath : StrBoolAttr<"unsafe-fp-math">; diff --git a/llvm/include/llvm/IR/CMakeLists.txt b/llvm/include/llvm/IR/CMakeLists.txt index dd8e04f1510c..eade87e05bc9 100644 --- a/llvm/include/llvm/IR/CMakeLists.txt +++ b/llvm/include/llvm/IR/CMakeLists.txt @@ -1,5 +1,6 @@ +set(LLVM_TARGET_DEFINITIONS Attributes.td) +tablegen(LLVM Attributes.inc -gen-attrs) + set(LLVM_TARGET_DEFINITIONS Intrinsics.td) - tablegen(LLVM Intrinsics.gen -gen-intrinsic) - add_public_tablegen_target(intrinsics_gen) diff --git a/llvm/lib/IR/Makefile b/llvm/lib/IR/Makefile index cc403f38dd8e..d5fc4033b467 100644 --- a/llvm/lib/IR/Makefile +++ b/llvm/lib/IR/Makefile @@ -10,14 +10,17 @@ LEVEL = ../.. LIBRARYNAME = LLVMCore BUILD_ARCHIVE = 1 -BUILT_SOURCES = $(PROJ_OBJ_ROOT)/include/llvm/IR/Intrinsics.gen +BUILT_SOURCES = $(PROJ_OBJ_ROOT)/include/llvm/IR/Intrinsics.gen \ + $(PROJ_OBJ_ROOT)/include/llvm/IR/Attributes.inc include $(LEVEL)/Makefile.common GENFILE:=$(PROJ_OBJ_ROOT)/include/llvm/IR/Intrinsics.gen +ATTRINCFILE:=$(PROJ_OBJ_ROOT)/include/llvm/IR/Attributes.inc INTRINSICTD := $(PROJ_SRC_ROOT)/include/llvm/IR/Intrinsics.td INTRINSICTDS := $(wildcard $(PROJ_SRC_ROOT)/include/llvm/IR/Intrinsics*.td) +ATTRIBUTESTD := $(PROJ_SRC_ROOT)/include/llvm/IR/Attributes.td $(ObjDir)/Intrinsics.gen.tmp: $(ObjDir)/.dir $(INTRINSICTDS) $(LLVM_TBLGEN) $(Echo) Building Intrinsics.gen.tmp from Intrinsics.td @@ -28,6 +31,19 @@ $(GENFILE): $(ObjDir)/Intrinsics.gen.tmp $(PROJ_OBJ_ROOT)/include/llvm/IR/.dir $(EchoCmd) Updated Intrinsics.gen because Intrinsics.gen.tmp \ changed significantly. ) +$(ObjDir)/Attributes.inc.tmp: $(ObjDir)/.dir $(ATTRIBUTESTD) $(LLVM_TBLGEN) + $(Echo) Building Attributes.inc.tmp from $(ATTRIBUTESTD) + $(Verb) $(LLVMTableGen) $(call SYSPATH, $(ATTRIBUTESTD)) -o $(call SYSPATH, $@) -gen-attrs + +$(ATTRINCFILE): $(ObjDir)/Attributes.inc.tmp $(PROJ_OBJ_ROOT)/include/llvm/IR/.dir + $(Verb) $(CMP) -s $@ $< || ( $(CP) $< $@ && \ + $(EchoCmd) Updated Attributes.inc because Attributes.inc.tmp \ + changed significantly. ) + install-local:: $(GENFILE) $(Echo) Installing $(DESTDIR)$(PROJ_includedir)/llvm/IR/Intrinsics.gen $(Verb) $(DataInstall) $(GENFILE) $(DESTDIR)$(PROJ_includedir)/llvm/IR/Intrinsics.gen + +install-local:: $(ATTRINCFILE) + $(Echo) Installing $(DESTDIR)$(PROJ_includedir)/llvm/IR/Attributes.inc + $(Verb) $(DataInstall) $(ATTRINCFILE) $(DESTDIR)$(PROJ_includedir)/llvm/IR/Attributes.inc diff --git a/llvm/utils/TableGen/Attributes.cpp b/llvm/utils/TableGen/Attributes.cpp new file mode 100644 index 000000000000..385a244d74d4 --- /dev/null +++ b/llvm/utils/TableGen/Attributes.cpp @@ -0,0 +1,59 @@ +//===- Attributes.cpp - Generate attributes -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include +#include +#include +using namespace llvm; + +#define DEBUG_TYPE "attr-enum" + +namespace { + +class Attributes { +public: + Attributes(RecordKeeper &R) : Records(R) {} + void emit(raw_ostream &OS); + +private: + void emitTargetIndependentEnums(raw_ostream &OS); + + RecordKeeper &Records; +}; + +} // End anonymous namespace. + +void Attributes::emitTargetIndependentEnums(raw_ostream &OS) { + OS << "#ifdef GET_ATTR_ENUM\n"; + OS << "#undef GET_ATTR_ENUM\n"; + + const std::vector &Attrs = + Records.getAllDerivedDefinitions("EnumAttr"); + + for (auto A : Attrs) + OS << A->getName() << ",\n"; + + OS << "#endif\n"; +} + +void Attributes::emit(raw_ostream &OS) { + emitTargetIndependentEnums(OS); +} + +namespace llvm { + +void EmitAttributes(RecordKeeper &RK, raw_ostream &OS) { + Attributes(RK).emit(OS); +} + +} // End llvm namespace. diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt index feaa7c757962..eef1540424dd 100644 --- a/llvm/utils/TableGen/CMakeLists.txt +++ b/llvm/utils/TableGen/CMakeLists.txt @@ -4,6 +4,7 @@ add_tablegen(llvm-tblgen LLVM AsmMatcherEmitter.cpp AsmWriterEmitter.cpp AsmWriterInst.cpp + Attributes.cpp CallingConvEmitter.cpp CodeEmitterGen.cpp CodeGenDAGPatterns.cpp diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp index 02fe4dc98bea..c16a5583eb36 100644 --- a/llvm/utils/TableGen/TableGen.cpp +++ b/llvm/utils/TableGen/TableGen.cpp @@ -41,7 +41,8 @@ enum ActionType { PrintEnums, PrintSets, GenOptParserDefs, - GenCTags + GenCTags, + GenAttributes }; namespace { @@ -85,6 +86,8 @@ namespace { "Generate option definitions"), clEnumValN(GenCTags, "gen-ctags", "Generate ctags-compatible index"), + clEnumValN(GenAttributes, "gen-attrs", + "Generate attributes"), clEnumValEnd)); cl::opt @@ -165,6 +168,9 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenCTags: EmitCTags(Records, OS); break; + case GenAttributes: + EmitAttributes(Records, OS); + break; } return false; diff --git a/llvm/utils/TableGen/TableGenBackends.h b/llvm/utils/TableGen/TableGenBackends.h index 2dc03ce1e71e..d9dd3d157697 100644 --- a/llvm/utils/TableGen/TableGenBackends.h +++ b/llvm/utils/TableGen/TableGenBackends.h @@ -78,6 +78,7 @@ void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS); void EmitMapTable(RecordKeeper &RK, raw_ostream &OS); void EmitOptParser(RecordKeeper &RK, raw_ostream &OS); void EmitCTags(RecordKeeper &RK, raw_ostream &OS); +void EmitAttributes(RecordKeeper &RK, raw_ostream &OS); } // End llvm namespace