Skip to content

[IR] Add "large" global variable property #69638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,9 @@ target supports it, it will emit globals to the section specified.
Additionally, the global can placed in a comdat if the target has the necessary
support.

For code models with a small/large data distinction, a global marked ``large``
is considered large regardless of its size.

External declarations may have an explicit section specified. Section
information is retained in LLVM IR for targets that make use of this
information. Attaching section information to an external declaration is an
Expand Down Expand Up @@ -755,7 +758,7 @@ Syntax::
[(unnamed_addr|local_unnamed_addr)] [AddrSpace]
[ExternallyInitialized]
<global | constant> <Type> [<InitializerConstant>]
[, section "name"] [, partition "name"]
[, section "name"] [, large] [, partition "name"]
[, comdat [($name)]] [, align <Alignment>]
[, no_sanitize_address] [, no_sanitize_hwaddress]
[, sanitize_address_dyninit] [, sanitize_memtag]
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/AsmParser/LLToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ enum Kind {
kw_addrspace,
kw_section,
kw_partition,
kw_large,
kw_alias,
kw_ifunc,
kw_module,
Expand Down
9 changes: 7 additions & 2 deletions llvm/include/llvm/IR/GlobalVariable.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,25 @@ class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
// Is this a global whose value can change from its initial value before
// global initializers are run?
bool isExternallyInitializedConstant : 1;
// Is this global unconditionally considered large in code models with a
// small/large data distinction?
bool isLargeGlobal : 1;

public:
/// GlobalVariable ctor - If a parent module is specified, the global is
/// automatically inserted into the end of the specified modules global list.
GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage,
Constant *Initializer = nullptr, const Twine &Name = "",
ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
bool isExternallyInitialized = false);
bool isExternallyInitialized = false, bool isLarge = false);
/// GlobalVariable ctor - This creates a global and inserts it before the
/// specified other global.
GlobalVariable(Module &M, Type *Ty, bool isConstant, LinkageTypes Linkage,
Constant *Initializer, const Twine &Name = "",
GlobalVariable *InsertBefore = nullptr,
ThreadLocalMode = NotThreadLocal,
std::optional<unsigned> AddressSpace = std::nullopt,
bool isExternallyInitialized = false);
bool isExternallyInitialized = false, bool isLarge = false);
GlobalVariable(const GlobalVariable &) = delete;
GlobalVariable &operator=(const GlobalVariable &) = delete;

Expand Down Expand Up @@ -159,6 +162,8 @@ class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
void setExternallyInitialized(bool Val) {
isExternallyInitializedConstant = Val;
}
bool isLarge() const { return isLargeGlobal; }
void setLarge(bool Val) { isLargeGlobal = Val; }

/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a GlobalVariable) from the GlobalVariable Src to this one.
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/AsmParser/LLLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(addrspace);
KEYWORD(section);
KEYWORD(partition);
KEYWORD(large);
KEYWORD(alias);
KEYWORD(ifunc);
KEYWORD(module);
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,9 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
return true;
if (Alignment)
GV->setAlignment(*Alignment);
} else if (Lex.getKind() == lltok::kw_large) {
GV->setLarge(true);
Lex.Lex();
} else if (Lex.getKind() == lltok::MetadataVar) {
if (parseGlobalObjectMetadataAttachment(*GV))
return true;
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3917,6 +3917,9 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
NewGV->setSanitizerMetadata(Meta);
}

if (Record.size() > 17 && Record[17])
NewGV->setLarge(Record[17]);

return Error::success();
}

Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1404,7 +1404,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
// GLOBALVAR: [strtab offset, strtab size, type, isconst, initid,
// linkage, alignment, section, visibility, threadlocal,
// unnamed_addr, externally_initialized, dllstorageclass,
// comdat, attributes, DSO_Local, GlobalSanitizer]
// comdat, attributes, DSO_Local, GlobalSanitizer, large]
Vals.push_back(addToStrtab(GV.getName()));
Vals.push_back(GV.getName().size());
Vals.push_back(VE.getTypeID(GV.getValueType()));
Expand All @@ -1421,7 +1421,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
GV.isExternallyInitialized() ||
GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass ||
GV.hasComdat() || GV.hasAttributes() || GV.isDSOLocal() ||
GV.hasPartition() || GV.hasSanitizerMetadata()) {
GV.hasPartition() || GV.hasSanitizerMetadata() || GV.isLarge()) {
Vals.push_back(getEncodedVisibility(GV));
Vals.push_back(getEncodedThreadLocalMode(GV));
Vals.push_back(getEncodedUnnamedAddr(GV));
Expand All @@ -1439,6 +1439,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
Vals.push_back((GV.hasSanitizerMetadata() ? serializeSanitizerMetadata(
GV.getSanitizerMetadata())
: 0));
Vals.push_back(GV.isLarge());
} else {
AbbrevToUse = SimpleGVarAbbrev;
}
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/IR/AsmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3642,6 +3642,8 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
printEscapedString(GV->getSection(), Out);
Out << '"';
}
if (GV->isLarge())
Out << ", large";
if (GV->hasPartition()) {
Out << ", partition \"";
printEscapedString(GV->getPartition(), Out);
Expand Down
9 changes: 5 additions & 4 deletions llvm/lib/IR/Globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,12 +414,13 @@ bool GlobalValue::canBeOmittedFromSymbolTable() const {
GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
Constant *InitVal, const Twine &Name,
ThreadLocalMode TLMode, unsigned AddressSpace,
bool isExternallyInitialized)
bool isExternallyInitialized, bool isLarge)
: GlobalObject(Ty, Value::GlobalVariableVal,
OperandTraits<GlobalVariable>::op_begin(this),
InitVal != nullptr, Link, Name, AddressSpace),
isConstantGlobal(constant),
isExternallyInitializedConstant(isExternallyInitialized) {
isExternallyInitializedConstant(isExternallyInitialized),
isLargeGlobal(isLarge) {
assert(!Ty->isFunctionTy() && PointerType::isValidElementType(Ty) &&
"invalid type for global variable");
setThreadLocalMode(TLMode);
Expand All @@ -435,12 +436,12 @@ GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
const Twine &Name, GlobalVariable *Before,
ThreadLocalMode TLMode,
std::optional<unsigned> AddressSpace,
bool isExternallyInitialized)
bool isExternallyInitialized, bool isLarge)
: GlobalVariable(Ty, constant, Link, InitVal, Name, TLMode,
AddressSpace
? *AddressSpace
: M.getDataLayout().getDefaultGlobalsAddressSpace(),
isExternallyInitialized) {
isExternallyInitialized, isLarge) {
if (Before)
Before->getParent()->insertGlobalVariable(Before->getIterator(), this);
else
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/TargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ TargetMachine::~TargetMachine() = default;
bool TargetMachine::isLargeData(const GlobalVariable *GV) const {
if (getTargetTriple().getArch() != Triple::x86_64 || GV->isThreadLocal())
return false;
if (GV->isLarge())
return true;
// Large data under the large code model still needs to be thought about, so
// restrict this to medium.
if (getCodeModel() != CodeModel::Medium)
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/Assembler/globalvariable-attributes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
@g7 = global i32 2, sanitize_address_dyninit, align 4
@g8 = global i32 2, sanitize_memtag, align 4
@g9 = global i32 2, no_sanitize_address, no_sanitize_hwaddress, sanitize_memtag, align 4
@g10 = global i32 2, large

attributes #0 = { "string" = "value" nobuiltin norecurse }

Expand All @@ -21,6 +22,7 @@ attributes #0 = { "string" = "value" nobuiltin norecurse }
; CHECK: @g7 = global i32 2, sanitize_address_dyninit, align 4
; CHECK: @g8 = global i32 2, sanitize_memtag, align 4
; CHECK: @g9 = global i32 2, no_sanitize_address, no_sanitize_hwaddress, sanitize_memtag, align 4
; CHECK: @g10 = global i32 2, large

; CHECK: attributes #0 = { "key"="value" "key2"="value2" }
; CHECK: attributes #1 = { "key3"="value3" }
Expand Down
108 changes: 78 additions & 30 deletions llvm/test/CodeGen/X86/code-model-elf.ll
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ target triple = "x86_64--linux"

@global_data = dso_local global [10 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0], align 16
@static_data = internal global [10 x i32] zeroinitializer, align 16
@always_large_static_data = internal global [10 x i32] zeroinitializer, align 16, large
@extern_data = external global [10 x i32], align 16
@thread_data = external thread_local global i32, align 4
@unknown_size_data = dso_local global [0 x i32] zeroinitializer, align 16
Expand Down Expand Up @@ -87,6 +88,53 @@ define dso_local ptr @lea_static_data() #0 {
ret ptr @static_data
}

define dso_local ptr @lea_always_large_static_data() #0 {
; SMALL-STATIC-LABEL: lea_always_large_static_data:
; SMALL-STATIC: # %bb.0:
; SMALL-STATIC-NEXT: movl $always_large_static_data, %eax
; SMALL-STATIC-NEXT: retq
;
; MEDIUM-STATIC-LABEL: lea_always_large_static_data:
; MEDIUM-STATIC: # %bb.0:
; MEDIUM-STATIC-NEXT: movabsq $always_large_static_data, %rax
; MEDIUM-STATIC-NEXT: retq
;
; LARGE-STATIC-LABEL: lea_always_large_static_data:
; LARGE-STATIC: # %bb.0:
; LARGE-STATIC-NEXT: movabsq $always_large_static_data, %rax
; LARGE-STATIC-NEXT: retq
;
; SMALL-PIC-LABEL: lea_always_large_static_data:
; SMALL-PIC: # %bb.0:
; SMALL-PIC-NEXT: leaq always_large_static_data(%rip), %rax
; SMALL-PIC-NEXT: retq
;
; MEDIUM-SMALL-DATA-PIC-LABEL: lea_always_large_static_data:
; MEDIUM-SMALL-DATA-PIC: # %bb.0:
; MEDIUM-SMALL-DATA-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx
; MEDIUM-SMALL-DATA-PIC-NEXT: movabsq $always_large_static_data@GOTOFF, %rax
; MEDIUM-SMALL-DATA-PIC-NEXT: addq %rcx, %rax
; MEDIUM-SMALL-DATA-PIC-NEXT: retq
;
; MEDIUM-PIC-LABEL: lea_always_large_static_data:
; MEDIUM-PIC: # %bb.0:
; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx
; MEDIUM-PIC-NEXT: movabsq $always_large_static_data@GOTOFF, %rax
; MEDIUM-PIC-NEXT: addq %rcx, %rax
; MEDIUM-PIC-NEXT: retq
;
; LARGE-PIC-LABEL: lea_always_large_static_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L1$pb:
; LARGE-PIC-NEXT: leaq .L1$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $always_large_static_data@GOTOFF, %rax
; LARGE-PIC-NEXT: addq %rcx, %rax
; LARGE-PIC-NEXT: retq
ret ptr @always_large_static_data
}

define dso_local ptr @lea_global_data() #0 {
; SMALL-STATIC-LABEL: lea_global_data:
; SMALL-STATIC: # %bb.0:
Expand Down Expand Up @@ -122,9 +170,9 @@ define dso_local ptr @lea_global_data() #0 {
;
; LARGE-PIC-LABEL: lea_global_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L1$pb:
; LARGE-PIC-NEXT: leaq .L1$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx
; LARGE-PIC-NEXT: .L2$pb:
; LARGE-PIC-NEXT: leaq .L2$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L2$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rax
; LARGE-PIC-NEXT: addq %rcx, %rax
Expand Down Expand Up @@ -165,9 +213,9 @@ define dso_local ptr @lea_extern_data() #0 {
;
; LARGE-PIC-LABEL: lea_extern_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L2$pb:
; LARGE-PIC-NEXT: leaq .L2$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L2$pb, %rcx
; LARGE-PIC-NEXT: .L3$pb:
; LARGE-PIC-NEXT: leaq .L3$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L3$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rax
; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax
Expand Down Expand Up @@ -212,9 +260,9 @@ define dso_local ptr @lea_unknown_size_data() #0 {
;
; LARGE-PIC-LABEL: lea_unknown_size_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L3$pb:
; LARGE-PIC-NEXT: leaq .L3$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L3$pb, %rcx
; LARGE-PIC-NEXT: .L4$pb:
; LARGE-PIC-NEXT: leaq .L4$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L4$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $unknown_size_data@GOTOFF, %rax
; LARGE-PIC-NEXT: addq %rcx, %rax
Expand Down Expand Up @@ -260,9 +308,9 @@ define dso_local i32 @load_global_data() #0 {
;
; LARGE-PIC-LABEL: load_global_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L4$pb:
; LARGE-PIC-NEXT: leaq .L4$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L4$pb, %rcx
; LARGE-PIC-NEXT: .L5$pb:
; LARGE-PIC-NEXT: leaq .L5$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L5$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rax
; LARGE-PIC-NEXT: movl 8(%rcx,%rax), %eax
Expand Down Expand Up @@ -310,9 +358,9 @@ define dso_local i32 @load_extern_data() #0 {
;
; LARGE-PIC-LABEL: load_extern_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L5$pb:
; LARGE-PIC-NEXT: leaq .L5$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L5$pb, %rcx
; LARGE-PIC-NEXT: .L6$pb:
; LARGE-PIC-NEXT: leaq .L6$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L6$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rax
; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax
Expand Down Expand Up @@ -361,9 +409,9 @@ define dso_local i32 @load_unknown_size_data() #0 {
;
; LARGE-PIC-LABEL: load_unknown_size_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L6$pb:
; LARGE-PIC-NEXT: leaq .L6$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L6$pb, %rcx
; LARGE-PIC-NEXT: .L7$pb:
; LARGE-PIC-NEXT: leaq .L7$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L7$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $unknown_size_data@GOTOFF, %rax
; LARGE-PIC-NEXT: movl 8(%rcx,%rax), %eax
Expand Down Expand Up @@ -421,9 +469,9 @@ define dso_local ptr @lea_static_fn() #0 {
;
; LARGE-PIC-LABEL: lea_static_fn:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L9$pb:
; LARGE-PIC-NEXT: leaq .L9$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L9$pb, %rcx
; LARGE-PIC-NEXT: .L10$pb:
; LARGE-PIC-NEXT: leaq .L10$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L10$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $static_fn@GOTOFF, %rax
; LARGE-PIC-NEXT: addq %rcx, %rax
Expand Down Expand Up @@ -464,9 +512,9 @@ define dso_local ptr @lea_global_fn() #0 {
;
; LARGE-PIC-LABEL: lea_global_fn:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L10$pb:
; LARGE-PIC-NEXT: leaq .L10$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L10$pb, %rcx
; LARGE-PIC-NEXT: .L11$pb:
; LARGE-PIC-NEXT: leaq .L11$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L11$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $global_fn@GOTOFF, %rax
; LARGE-PIC-NEXT: addq %rcx, %rax
Expand Down Expand Up @@ -507,9 +555,9 @@ define dso_local ptr @lea_extern_fn() #0 {
;
; LARGE-PIC-LABEL: lea_extern_fn:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L11$pb:
; LARGE-PIC-NEXT: leaq .L11$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L11$pb, %rcx
; LARGE-PIC-NEXT: .L12$pb:
; LARGE-PIC-NEXT: leaq .L12$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L12$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $extern_fn@GOT, %rax
; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax
Expand Down Expand Up @@ -585,9 +633,9 @@ define dso_local float @load_constant_pool(float %x) #0 {
;
; LARGE-PIC-LABEL: load_constant_pool:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L13$pb:
; LARGE-PIC-NEXT: leaq .L13$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L13$pb, %rcx
; LARGE-PIC-NEXT: .L14$pb:
; LARGE-PIC-NEXT: leaq .L14$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L14$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq ${{\.?LCPI[0-9]+_[0-9]+}}@GOTOFF, %rax
; LARGE-PIC-NEXT: addss (%rcx,%rax), %xmm0
Expand Down