Skip to content
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
1 change: 1 addition & 0 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -3558,6 +3558,7 @@ OPT_LIST(V)
PSF_Execute = 0x4,
PSF_Implicit = 0x8,
PSF_ZeroInit = 0x10,
PSF_Shared = 0x20,
PSF_Invalid = 0x80000000U,
};

Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5696,6 +5696,10 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
const ASTContext::SectionInfo &SI = Context.SectionInfos[SA->getName()];
if ((SI.SectionFlags & ASTContext::PSF_Write) == 0)
GV->setConstant(true);
Comment on lines 5697 to 5698
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks to be where the constant specifier is coming from in the test case; absence of PSF_Write implies constant. Here is a suggestion, but there might be a better way to reorganize how these flags are checked; I haven't given it much thought.

Suggested change
if ((SI.SectionFlags & ASTContext::PSF_Write) == 0)
GV->setConstant(true);
if ((SI.SectionFlags & ASTContext::PSF_Write) == 0 &&
SI.SectionFlags & ASTContext::PSF_Shared) == 0)
GV->setConstant(true);

if ((SI.SectionFlags & ASTContext::PSF_Execute) != 0)
GV->setExecute(true);
if ((SI.SectionFlags & ASTContext::PSF_Shared) != 0)
GV->setShared(true);
}

CharUnits AlignVal = getContext().getDeclAlign(D);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Parse/ParsePragma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,7 @@ bool Parser::HandlePragmaMSSection(StringRef PragmaName,
.Case("read", ASTContext::PSF_Read)
.Case("write", ASTContext::PSF_Write)
.Case("execute", ASTContext::PSF_Execute)
.Case("shared", ASTContext::PSF_Invalid)
.Case("shared", ASTContext::PSF_Shared)
.Case("nopage", ASTContext::PSF_Invalid)
.Case("nocache", ASTContext::PSF_Invalid)
.Case("discard", ASTContext::PSF_Invalid)
Expand Down
7 changes: 7 additions & 0 deletions clang/test/CodeGenCXX/sections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ __declspec(allocate("short_section")) short short_var = 42;
struct t2 { t2(); };
extern const t2 non_trivial_ctor;
__declspec(allocate("non_trivial_ctor_section")) const t2 non_trivial_ctor_var;
#pragma section("mysec", shared)
int j = 0;
__declspec(allocate("mysec")) int k = 0;
extern __declspec(allocate("mysec")) int var = 10;
}


Expand Down Expand Up @@ -130,6 +134,9 @@ __declspec(allocate("non_trivial_ctor_section")) const t2 non_trivial_ctor_var;
//CHECK: @long_var = dso_local global i32 42, section "long_section"
//CHECK: @short_var = dso_local global i16 42, section "short_section"
//CHECK: @non_trivial_ctor_var = internal global %struct.t2 zeroinitializer, section "non_trivial_ctor_section"
//CHECK: @j = dso_local global i32 0, section ".data", align 4
//CHECK: @k = dso_local constant i32 0, section "mysec", align 4
//CHECK: @var = dso_local constant i32 10, section "mysec", align 4
//CHECK: define dso_local void @g()
//CHECK: define dso_local void @h() {{.*}} section ".my_code"
//CHECK: define dso_local void @h2() {{.*}} section ".my_code"
12 changes: 10 additions & 2 deletions llvm/include/llvm/IR/GlobalVariable.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ 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;
bool isExecuteGlobal : 1;
bool isSharedGlobal : 1;

private:
static const unsigned CodeModelBits = LastCodeModelBit - LastAlignmentBit;
Expand All @@ -60,15 +62,17 @@ class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
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 isExecuteGlobal = false,
bool isSharedGlobal = 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 isExecuteGlobal = false, bool isSharedGlobal = false);
GlobalVariable(const GlobalVariable &) = delete;
GlobalVariable &operator=(const GlobalVariable &) = delete;

Expand Down Expand Up @@ -179,6 +183,10 @@ class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
void setExternallyInitialized(bool Val) {
isExternallyInitializedConstant = Val;
}
bool isExecute() const { return isExecuteGlobal; }
bool isShared() const { return isSharedGlobal; }
void setExecute(bool Val) { isExecuteGlobal = Val; }
void setShared(bool Val) { isSharedGlobal = Val; }

/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a GlobalVariable) from the GlobalVariable Src to this one.
Expand Down
5 changes: 4 additions & 1 deletion llvm/include/llvm/MC/SectionKind.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class SectionKind {
enum Kind {
/// Metadata - Debug info sections or other metadata.
Metadata,

/// Shared
Shared,
/// Exclude - This section will be excluded from the final executable or
/// shared library. Only valid for ELF / COFF targets.
Exclude,
Expand Down Expand Up @@ -153,6 +154,7 @@ class SectionKind {
bool isWriteable() const {
return isThreadLocal() || isGlobalWriteableData();
}
bool isShared() const { return K == Shared; }

bool isThreadLocal() const {
return K == ThreadData || K == ThreadBSS || K == ThreadBSSLocal;
Expand Down Expand Up @@ -190,6 +192,7 @@ class SectionKind {
static SectionKind getText() { return get(Text); }
static SectionKind getExecuteOnly() { return get(ExecuteOnly); }
static SectionKind getReadOnly() { return get(ReadOnly); }
static SectionKind getShared() { return get(Shared); }
static SectionKind getMergeable1ByteCString() {
return get(Mergeable1ByteCString);
}
Expand Down
39 changes: 15 additions & 24 deletions llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1599,37 +1599,28 @@ getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) {
bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb;

if (K.isMetadata())
Flags |=
COFF::IMAGE_SCN_MEM_DISCARDABLE;
Flags |= COFF::IMAGE_SCN_MEM_DISCARDABLE;
else if (K.isExclude())
Flags |=
COFF::IMAGE_SCN_LNK_REMOVE | COFF::IMAGE_SCN_MEM_DISCARDABLE;
Flags |= COFF::IMAGE_SCN_LNK_REMOVE | COFF::IMAGE_SCN_MEM_DISCARDABLE;
else if (K.isText())
Flags |=
COFF::IMAGE_SCN_MEM_EXECUTE |
COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_CNT_CODE |
(isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0);
COFF::IMAGE_SCN_MEM_EXECUTE | COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_CNT_CODE |
(isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0);
else if (K.isBSS())
Flags |=
COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE;
Flags |= COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE;
else if (K.isThreadLocal())
Flags |=
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE;
Flags |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE;
else if (K.isReadOnly() || K.isReadOnlyWithRel())
Flags |=
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ;
Flags |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ;
else if (K.isWriteable())
Flags |=
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE;

Flags |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE;
else if (K.isShared())
Flags |= COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE |
COFF::IMAGE_SCN_MEM_SHARED;
return Flags;
}

Expand Down
11 changes: 7 additions & 4 deletions llvm/lib/IR/Globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,11 +447,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 isExecute,
bool isShared)
: GlobalObject(Ty, Value::GlobalVariableVal, AllocMarker, Link, Name,
AddressSpace),
isConstantGlobal(constant),
isExternallyInitializedConstant(isExternallyInitialized) {
isExternallyInitializedConstant(isExternallyInitialized),
isExecuteGlobal(isExecute), isSharedGlobal(isShared) {
assert(!Ty->isFunctionTy() && PointerType::isValidElementType(Ty) &&
"invalid type for global variable");
setThreadLocalMode(TLMode);
Expand All @@ -469,12 +471,13 @@ GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
const Twine &Name, GlobalVariable *Before,
ThreadLocalMode TLMode,
std::optional<unsigned> AddressSpace,
bool isExternallyInitialized)
bool isExternallyInitialized, bool isExecute,
bool isShared)
: GlobalVariable(Ty, constant, Link, InitVal, Name, TLMode,
AddressSpace
? *AddressSpace
: M.getDataLayout().getDefaultGlobalsAddressSpace(),
isExternallyInitialized) {
isExternallyInitialized, isExecute, isShared) {
if (Before)
Before->getParent()->insertGlobalVariable(Before->getIterator(), this);
else
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/Target/TargetLoweringObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,11 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO,
// into a mergable section: just drop it into the general read-only
// section instead.
if (!GVar->hasGlobalUnnamedAddr())
return SectionKind::getReadOnly();
if (GVar->isExecute())
return SectionKind::getExecuteOnly();
if (GVar->isShared())
return SectionKind::getShared();
return SectionKind::getReadOnly();

// If initializer is a null-terminated string, put it in a "cstring"
// section of the right width.
Expand Down
Loading